[winapi] Exporting functions from a DLL with dllexport

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.

This question is related to winapi visual-c++ dll name-decoration

The answer is


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?


For C++ :

I just faced the same issue and I think it is worth mentioning a problem comes up when one use both __stdcall (or WINAPI) and extern "C":

As you know extern "C" removes the decoration so that instead of :

__declspec(dllexport) int Test(void)                        --> dumpbin : ?Test@@YaHXZ

you obtain a symbol name undecorated:

extern "C" __declspec(dllexport) int Test(void)             --> dumpbin : Test

However the _stdcall ( = macro WINAPI, that changes the calling convention) also decorates names so that if we use both we obtain :

   extern "C" __declspec(dllexport) int WINAPI Test(void)   --> dumpbin : _Test@0

and the benefit of extern "C" is lost because the symbol is decorated (with _ @bytes)

Note that this only occurs for x86 architecture because the __stdcall convention is ignored on x64 (msdn : on x64 architectures, by convention, arguments are passed in registers when possible, and subsequent arguments are passed on the stack.).

This is particularly tricky if you are targeting both x86 and x64 platforms.


Two solutions

  1. Use a definition file. But this forces you to maintain the state of the def file.

  2. the simplest way : define the macro (see msdn) :

#define EXPORT comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__)

and then include the following pragma in the function body:

#pragma EXPORT

Full Example :

 int WINAPI Test(void)
{
    #pragma EXPORT
    return 1;
}

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


Examples related to winapi

ImportError: no module named win32api Why does CreateProcess give error 193 (%1 is not a valid Win32 app) Dynamically load a function from a DLL How to check if directory exist using C++ and winAPI How to convert char* to wchar_t*? Get current cursor position Check whether a path is valid How do I link to a library with Code::Blocks? Where to find the win32api module for Python? Cannot open include file 'afxres.h' in VC2010 Express

Examples related to visual-c++

How to install Visual C++ Build tools? Microsoft Visual C++ 14.0 is required (Unable to find vcvarsall.bat) How to install numpy on windows using pip install? How to use _CRT_SECURE_NO_WARNINGS How to play or open *.mp3 or *.wav sound file in c++ program? What is C# equivalent of <map> in C++? The program can't start because MSVCR110.dll is missing from your computer error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700' in CppFile1.obj Identifier is undefined error LNK2001: unresolved external symbol (C++)

Examples related to dll

The program can't start because api-ms-win-crt-runtime-l1-1-0.dll is missing while starting Apache server on my computer PHP 7: Missing VCRUNTIME140.dll How to fix PHP Warning: PHP Startup: Unable to load dynamic library 'ext\\php_curl.dll'? WampServer: php-win.exe The program can't start because MSVCR110.dll is missing msvcr110.dll is missing from computer error while installing PHP installing JDK8 on Windows XP - advapi32.dll error The program can’t start because MSVCR71.dll is missing from your computer. Try reinstalling the program to fix this program ImportError: DLL load failed: %1 is not a valid Win32 application. But the DLL's are there Loading DLLs at runtime in C# Missing `server' JVM (Java\jre7\bin\server\jvm.dll.)

Examples related to name-decoration

Exporting functions from a DLL with dllexport