Cygwin 64-bit cannot early-bind to DLL created by MSVC , giving __cxa_atexit error

风流意气都作罢 提交于 2020-06-16 17:01:18

问题


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 and GetProcAddress, 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!