<p>I'm stuck on a fix to a legacy Visual C++ 6 app. In the C++ DLL source I have put</p>

<pre><code>extern "C" _declspec(dllexport) char* MyNewVariable = 0;
</code></pre>

<p>which results in MyNewVariable showing up (nicely undecorated) in the export table (as shown by dumpbin /exports blah.dll). However, I can't figure out how to declare the variable so that I can access it in a C source file. I have tried various things, including</p>

<pre><code>_declspec(dllimport) char* MyNewVariable;
</code></pre>

<p>but that just gives me a linker error:</p>

<p>unresolved external symbol "__declspec(dllimport) char * MyNewVariable" (__imp_?MyNewVariable@@3PADA)</p>

<pre><code>extern "C" _declspec(dllimport) char* MyNewVariable;
</code></pre>

<p>as suggested by Tony (and as I tried before) results in a different expected decoration, but still hasn't removed it:</p>

<p>unresolved external symbol __imp__MyNewVariable</p>

<p>How do I write the declaration so that the C++ DLL variable is accessible from the C app?</p>

<hr>

<h2>The Answer</h2>

<p>As identified by botismarius and others (many thanks to all), I needed to link with the DLL's .lib. To prevent the name being mangled I needed to declare it (in the C source) with no decorators, which means I needed to use the .lib file.</p>

[{'answer_id': 56513, 'author': 'Tony Lee', 'author_id': 5819, 'author_profile': 'https://Stackoverflow.com/users/5819', 'pm_score': 2, 'selected': False, 'text': '<p>extern "C" is how you remove decoration - it should work to use:</p>\n\n<p>extern "C" declspec(dllimport) char MyNewVariable;</p>\n\n<p>or if you want a header that can be used by C++ or C (with /TC switch)</p>\n\n<pre><code>#ifdef __cplusplus\nextern "C" {\n#endif\ndeclspec(dllimport) char MyNewVariable;\n#ifdef __cplusplus\n}\n#endif\n</code></pre>\n\n<p>And of course, link with the import library generated by the dll doing the export.</p>\n'}, {'answer_id': 56514, 'author': 'botismarius', 'author_id': 4528, 'author_profile': 'https://Stackoverflow.com/users/4528', 'pm_score': 4, 'selected': True, 'text': '<p>you must link against the lib generated after compiling the DLL. In the linker options of the project, you must add the <code>.lib</code> file. And yes, you should also declare the variable as:</p>\n\n<pre><code>extern "C" { declspec(dllimport) char MyNewVariable; }\n</code></pre>\n'}, {'answer_id': 56535, 'author': 'spoulson', 'author_id': 3347, 'author_profile': 'https://Stackoverflow.com/users/3347', 'pm_score': 2, 'selected': False, 'text': "<p>I'm not sure who downmodded botismarius, because he's right.  The reason is the .lib generated is the import library that makes it easy to simply declare the external variable/function with <code>__declspec(dllimport)</code> and just use it.  The import library simply automates the necessary <code>LoadLibrary()</code> and <code>GetProcAddress()</code> calls.  Without it, you need to call these manually.</p>\n"}, {'answer_id': 56541, 'author': 'Graeme Perrow', 'author_id': 1821, 'author_profile': 'https://Stackoverflow.com/users/1821', 'pm_score': 1, 'selected': False, 'text': '<p>They\'re both right. The fact that the error message describes <code>__imp_?MyNewVariable@@3PADA</code> means that it\'s looking for the decorated name, so the extern "C" is necessary. However, linking with the import library is <strong>also</strong> necessary or you\'ll just get a different link error.</p>\n'}, {'answer_id': 56550, 'author': 'spoulson', 'author_id': 3347, 'author_profile': 'https://Stackoverflow.com/users/3347', 'pm_score': 1, 'selected': False, 'text': '<p>@Graeme: You\'re right on that, too.  I think the "C" compiler that the OP is using is not enforcing C99 standard, but compiling as C++, thus mangling the names.  A true C compiler wouldn\'t understand the "C" part of the <code>extern "C"</code> keyword.</p>\n'}, {'answer_id': 56649, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>I\'ve never used _declspec(dllimport) when I was programming in Windows. You should be able to simply declare </p>\n\n<pre><code>extern "C" char* MyNewVariable;\n</code></pre>\n\n<p>and link to the .libb created when DLL was compiled.</p>\n'}, {'answer_id': 57055, 'author': 'Bart', 'author_id': 4343, 'author_profile': 'https://Stackoverflow.com/users/4343', 'pm_score': 1, 'selected': False, 'text': '<p>In the <strong>dll source code</strong> you should have this implementation so that the .lib file <em>exports</em> the symbol:</p>\n\n<pre><code>extern "C" _declspec(dllexport) char* MyNewVariable = 0;\n</code></pre>\n\n<p>The c client should use a <strong>header</strong> with this declaration so that the client code will <em>import</em> the symbol:</p>\n\n<pre><code>extern "C" _declspec(dllimport) char* MyNewVariable;\n</code></pre>\n\n<p>This header will cause a compile error if #include-ed in the dll source code, so it is usually put in an export header that is used only for exported functions and only by clients.</p>\n\n<p>If you need to, you can also create a "universal" header that can be included anywhere that looks like this:</p>\n\n<pre><code>#ifdef __cplusplus\nextern "C" {\n#endif\n#ifdef dll_source_file\n#define EXPORTED declspec(dllexport) \n#else\n#define EXPORTED declspec(dllimport) \n#endif dll_source_file\n#ifdef __cplusplus\n}\n#endif\n\nEXPORTED char* MyNewVariable;\n</code></pre>\n\n<p>Then the dll source code looks like this:</p>\n\n<pre><code>#define dll_source_code \n#include "universal_header.h"\n\nEXPORTED char* MyNewVariable = 0;\n</code></pre>\n\n<p>And the client looks like this:</p>\n\n<pre><code>#include "universal_header.h"\n...\nMyNewVariable = "Hello, world";\n</code></pre>\n\n<p>If you do this a lot, the monster #ifdef at the top can go in export_magic.h and universal_header.h becomes:</p>\n\n<pre><code>#include "export_magic.h"\n\nEXPORTED char *MyNewVariable;\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/56500', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5816/']