1

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).

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Don't know much about the cygwin side of it, but on the VC side the following may provide some more clues. Whether it works if you remove the __declspec(...) at both ends. Whether the DLL was linked statically or dynamically to the VCRT. Whether it works with a .lib generated by some tool other than the VC linker. – dxiv May 15 '20 at 06:05
  • may be https://cygwin.com/cygwin-ug-net/dll.html#dll-link – matzeri May 15 '20 at 10:00
  • https://stackoverflow.com/questions/56855348/paradoxon-silent-crash-on-pythons-ctypes-cdll-when-importing-but-not-when-run – CristiFati May 15 '20 at 19:46
  • @matzeri that page is mostly about creating Cygwin DLLs (and the part at the bottom doesn't work as the DLL is stripped apparently) – M.M May 16 '20 at 03:04
  • @dxiv disabling static linking has no effect on the problem; and removing __declspec(dllexport) causes VS to not even create an import library for the DLL so there is nothing to link against. – M.M May 17 '20 at 20:52
  • @M.M Right, I was thinking at exporting the old fashioned way with a .def file but forgot to write it. Anyway, that's a most curious error you've got there. – dxiv May 17 '20 at 21:16
  • @dxiv yeah. I've posted to the Cygwin mailing list now so hopefully something will turn up. As a workaround I guess I can make a manual "import library" that does late binding ... – M.M May 17 '20 at 21:38
  • (update) nobody on the Cygwin mailing list could help – M.M Jun 04 '20 at 20:46

0 Answers0