Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't access variable in C++ DLL from a C app

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

extern "C" _declspec(dllexport) char* MyNewVariable = 0;

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

_declspec(dllimport) char* MyNewVariable;

but that just gives me a linker error:

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

extern "C" _declspec(dllimport) char* MyNewVariable;

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

unresolved external symbol __imp__MyNewVariable

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


The Answer

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.

like image 586
Ian Horwill Avatar asked Sep 11 '08 13:09

Ian Horwill


4 Answers

you must link against the lib generated after compiling the DLL. In the linker options of the project, you must add the .lib file. And yes, you should also declare the variable as:

extern "C" { declspec(dllimport) char MyNewVariable; }
like image 179
botismarius Avatar answered Nov 13 '22 17:11

botismarius


extern "C" is how you remove decoration - it should work to use:

extern "C" declspec(dllimport) char MyNewVariable;

or if you want a header that can be used by C++ or C (with /TC switch)

#ifdef __cplusplus
extern "C" {
#endif
declspec(dllimport) char MyNewVariable;
#ifdef __cplusplus
}
#endif

And of course, link with the import library generated by the dll doing the export.

like image 28
Tony Lee Avatar answered Nov 13 '22 19:11

Tony Lee


@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 extern "C" keyword.

like image 26
spoulson Avatar answered Nov 13 '22 18:11

spoulson


They're both right. The fact that the error message describes __imp_?MyNewVariable@@3PADA means that it's looking for the decorated name, so the extern "C" is necessary. However, linking with the import library is also necessary or you'll just get a different link error.

like image 1
Graeme Perrow Avatar answered Nov 13 '22 19:11

Graeme Perrow