问题
Here is the C++ program compiled by up-to-date Cygwin64 (gcc/x86_84-pc-cygwin/9.3.0):
extern "C"
__declspec(dllimport) void foo(void);
int main(void)
{
foo();
return 0;
}
with commandline:
g++ -o mre.exe mre.cc /f/temp/simpledll/x64/Debug/simpledll.lib
For SimpleDLL I created a new Windows C++ DLL using VS Community 2019, switched to x64 target, disabled PCH, and added simpledll.cpp:
extern "C" __declspec(dllexport) void foo(void);
void foo(void)
{
MessageBoxA(NULL, "In simpledll foo", "Title", MB_OK);
}
leaving the rest of the DLL boilerplate unchanged.
The compilation in Cygwin64 runs successfully, but then running the executable under the Cygwin shell exits with no output. Running the executable in command prompt (and the cygwin1.dll and simpledll.dll in the same directory as the executable, to eliminate any path errors) produces a message box with the text:
The procedure entry point __cxa_atexit could not be located in the dynamic link library F:\temp\mre.exe
Via a debugger (WinDBG) and ProcMon64 I can see that during startup, simpledll.dll
is opened correctly and read; and then this error appears (with a C0000139 error code visible in WinDBG when the __cxa_atexit messagebox appears). This happens even if the main()
function never calls the function (e.g. I change it to if (argc > 1) foo();
and provide no commandline arguments).
However the following work correctly, showing the messagebox from foo
:
- The exact same procedure under a mingw-w64 standalone (either from MSYS2 shell, or command prompt).
- The exact same procedure under MSYS2 (x86_64-pc-msys2).
- Under Cygwin or MSYS2, loading the same DLL via
LoadLibrary
andGetProcAddress
, instead of linking to the.lib
file. That is, late binding works fine whereas early binding crashes.
I've been unable to figure out what is happening differently in the Cygwin targets versus any of the above bullet points. Using -fuse-cxa-atexit
makes no difference (I think this is on by default anyway), and strings mre.exe
shows __cxa_atexit
and __imp___cxa_atexit
existing. Furthermore, in the standalone mingw-w64 builds, strings
does not find any cxa
at all, and yet the code runs correctly.
My question is: what is going wrong and how do I fix it (i.e. how can I call a function in the MSVC-created x64 DLL from a Cygwin64-target build).
来源:https://stackoverflow.com/questions/61812131/cygwin-64-bit-cannot-early-bind-to-dll-created-by-msvc-giving-cxa-atexit-err