Reputation: 31512
There are similar questions here but they don't quite answer my question:
When I cross-compile a DLL from Mac OS X using MinGW and wclang, why does my DLL work fine without using __declspec
?
The MinGW DLL sample docs, and every reference I see to doing this, say to use __declspec(dllexport)
before function declarations. Yet none of the code in my 9,000-line library uses it, and the DLL works great!
For example, here's a contrived example library built in the same way:
#include <stdio.h>
extern "C" {
int hello(const char* name) {
printf("Hello, %s!\n", name);
return 0;
}
}
Compiled with this on Mac OS X 10.10.3:
w32-clang++ test.cpp -shared -o test.dll
Produces a fine-looking DLL:
And my Windows application:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
typedef int(*hellofn)(const char*);
int _tmain(int argc, _TCHAR* argv[])
{
DWORD err;
HINSTANCE dll = LoadLibrary(L"E:\\test.dll");
if (!dll) {
err = GetLastError();
std::cout << "Can't load library: " << err << std::endl;
return 1;
}
hellofn hello = (hellofn)GetProcAddress(dll, "hello");
if (!hello) {
err = GetLastError();
std::cout << "Could not load the function: " << err << std::endl;
return 2;
}
int ret = hello("nerd");
std::cout << "hello() returned " << ret << std::endl;
return 0;
}
Works great:
Am I shooting myself in the foot somehow, or is there some magic that I'm not seeing? I'm thinking that wclang (MinGW+clang) knows to use __stdcall
automatically somehow and doesn't mangle the function names?
Upvotes: 3
Views: 3027
Reputation: 2034
No, you do not need __declspec(dllexport)
, when building a DLL with MinGW; (in fact, I frequently omit it myself). The caveat is that, if just one symbol to be included in the DLL is so decorated, then all others you wish to have exported must be likewise decorated, (unless you pass the --export-all-symbols
option to the linker when you build the DLL).
If you include only undecorated symbols, then all global symbols will be exported, just as if --export-all-symbols
were specified by default.
However, this has nothing whatsoever to do with __stdcall
vs. __cdecl
calling conventions, or name mangling; it is solely a determinant of the visibility of symbols in the DLL's export table. If you don't declare your functions to be __stdcall
or __cdecl
, then they will be __cdecl
by default; that's no problem, provided both providing DLL and caller agree on that convention. Similarly, if both agree on any name mangling convention, (which normally means that, in the case of C++ in particular, they both used the same compiler at build time), then there will be no linking problems.
Upvotes: 4