I'd like a simple example of exporting a function from a C++ windows DLL.
I'd like to see the header, the cpp file, and the def file (if absolutely required).
I'd like the exported name to be undecorated. I'd like to use the most standard calling convention (__stdcall?). I'd like the use __declspec(dllexport) and not have to use a DEF file.
For example:
//header
extern "C"
{
__declspec(dllexport) int __stdcall foo(long bar);
}
//cpp
int __stdcall foo(long bar)
{
return 0;
}
I'm trying to avoid the linker added underscores and/or numbers (byte counts?) to the name.
I'm OK with not supporting dllimport and dllexport using the same header. I don't want any information about exporting C++ class methods, just c-style global functions.
UPDATE
Not including the calling convention (and using extern "C") gives me the export names as I like, but what does that mean? Is whatever default calling convention I'm getting what pinvoke (.NET), declare (vb6), and GetProcAddress would expect? (I guess for GetProcAddress it would depend on the function pointer the caller created).
I want this DLL to be used without a header file, so I don't really need the a lot of the fancy #defines to make the header usable by a caller.
I'm OK with an answer being that I have to use a DEF file.
I think _naked might get what you want, but it also prevents the compiler from generating the stack management code for the function. extern "C" causes C style name decoration. Remove that and that should get rid of your _'s. The linker doesn't add the underscores, the compiler does. stdcall causes the argument stack size to be appended.
For more, see: http://en.wikipedia.org/wiki/X86_calling_conventions http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx
The bigger question is why do you want to do that? What's wrong with the mangled names?
If you want plain C exports, use a C project not C++. C++ DLLs rely on name-mangling for all the C++isms (namespaces etc...). You can compile your code as C by going into your project settings under C/C++->Advanced, there is an option "Compile As" which cooresponds to the compiler switches /TP and /TC.
Exporting/Importing DLL Libs in VC++
What you really want to do is define a conditional macro in a header that will be included in all of the source files in your DLL project:
Then on a function that you want to be exported you use
LIBRARY_API
:In your library build project create a define
LIBRARY_EXPORTS
this will cause your functions to be exported for your DLL build.Since
LIBRARY_EXPORTS
will not be defined in a project consuming the DLL, when that project includes the header file of your library all of the functions will be imported instead.If your library is to be cross-platform you can define LIBRARY_API as nothing when not on Windows:
When using dllexport/dllimport you do not need to use DEF files, if you use DEF files you do not need to use dllexport/dllimport. The two methods accomplish the same task different ways, I believe that dllexport/dllimport is the recommended method out of the two.
Exporting unmangled functions from a C++ DLL for LoadLibrary/PInvoke
If you need this to use LoadLibrary and GetProcAddress, or maybe doing PInvoke from .NET you can use
extern "C"
inline with your dllexport. And since we are using GetProcAddress instead of dllimport we don't need to do the ifdef dance from above, just a simple dllexport:The Code:
And here's what the exports look like with Dumpbin /exports:
So this code works fine:
For C++ :
I just faced the same issue and I think it is worth mentioning a problem comes up when one use both
__stdcall
(orWINAPI
) andextern "C"
:As you know
extern "C"
removes the decoration so that instead of :you obtain a symbol name undecorated:
However the
_stdcall
( = macro WINAPI, that changes the calling convention) also decorates names so that if we use both we obtain :and the benefit of
extern "C"
is lost because the symbol is decorated (with _ @bytes)This is particularly tricky if you are targeting both x86 and x64 platforms.
Two solutions
Use a definition file. But this forces you to maintain the state of the def file.
the simplest way : define the macro (see msdn) :
and then include the following pragma in the function body:
Full Example :
This will export the function undecorated for both x86 and x64 targets while preserving the
__stdcall
convention for x86. The__declspec(dllexport)
is not required in this case.I had exactly the same problem, my solution was to use module definition file (.def) instead of
__declspec(dllexport)
to define exports(http://msdn.microsoft.com/en-us/library/d91k01sh.aspx). I have no idea why this works, but it does