I have an Application and DLL project that I am trying to port to a 64-bit environment. I ran into an issue with the DLL module definition that would cause linker errors such as the following when compiled with a 64-bit configuration:
2>mylib.exp : error LNK2001: unresolved external symbol _func_a@4
2>mylib.exp : error LNK2001: unresolved external symbol _func_b@4
The header definition for these functions looks like:
#ifdef MYLIB_DEF
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
DLLEXPORT extern int variable;
DLLEXPORT int __stdcall func_a(int value);
DLLEXPORT int __stdcall func_b(int value);
And in the C source file, it starts with this:
#define MYLIB_DEF
#include "mylib.h"
DLLEXPORT int variable;
DLLEXPORT int __stdcall func_a(int value)
{
...
Now, for the trouble part. We have something like this for the module definition file:
LIBRARY mylib.dll
EXPORTS
variable DATA
_func_a@4
func_a@4=_func_a@4
func_a=_func_a@4
_func_b@4
func_b@4=_func_a@4
func_b=_func_a@4
This triggers the aforementioned errors. I understand that MSVC decorates functions when compiled with __stdcall
and 64-bit builds don't use/support __stdcall
so there are no decorations. I was able to create an alternate definition file that seems to work like this:
LIBRARY mylib.dll
EXPORTS
variable DATA
func_a
func_b
But, as this file was last touched 10 years ago, I don't know if I understand all the implications or reasoning behind the use of this file. Would something like that file be adequate for 64-bit builds. While our app is the primary user of our DLL, we do have others that interface to the DLL directly so I do not want to break any compatibility, however, we have zero users of a 64-bit version at the moment.
Do we need the definition file at all if we are using __declspec(dllexport)
everywhere and not using ordinal exports?
Should we just drop it for 64-bit builds or does it provide any value?
Does dropping it from 32-bit builds as unneeded noise risk breaking any external users? From local testing, it does not seem to be required, but I am doing a full rebuild of the app and DLL.
Why does every function need two additional aliases? Is this standard practice for 32-bit builds? Is there a 64-bit equivalent we should be doing?
I've looked over Microsoft's documentation on the topic, but it says nothing about 64-bit builds versus 32-bit builds:
https://learn.microsoft.com/en-us/cpp/build/reference/exports?view=msvc-170