我已经阅读了这里的所有内容以及我在网上可以找到的所有关于这样做的信息,但这些信息已经过时、相互矛盾或不适用。我有一个非常简单的 C 库,我将其编译为 Linux 中的共享库,并且一切正常。我想将此移植到 Windows DLL。自 1990 年代以来我就没有对 Windows 进行过编程,但我对它的复杂性并不是完全一无所知(事实上,它们是我使用 Linux 的原因:-)。
生成库的 MinGW 编译器行是这样的(由 cmake 生成):
gcc.exe -Wl,--export-all -Wl,--enable-auto-import -shared -o libonejoker.dll -Wl,--out-implib,libonejoker.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -Wl,--whole-archive CMakeFiles/onejoker.dir/objects.a -Wl,--no-whole-archive -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
不知道为什么或是否需要所有这些库,因为我根本没有在库中进行任何操作系统调用,但是 cmake 将它们放在那里。这将创建 dll 和 .dll.a。我告诉 cmake 添加 -Wl,--export-all,尽管这应该是默认值。尝试将我的简单测试程序与新创建的 dll 链接这样做:
gcc.exe -g @CMakeFiles/test004.dir/includes_C.rsp -o CMakeFiles/test004.dir/test004.c.obj -c /c/Users/Lee/Projects/OneJoker/src/tests/test004.c
gcc.exe -g -Wl,--whole-archive CMakeFiles/test004.dir/objects.a -Wl,--no-whole-archive -o test004.exe -Wl,--out-implib,libtest004.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -L/C/Users/Lee/Projects/OneJoker/build/src/lib ../lib/libonejoker.dll.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
如果程序“test004”没有从 DLL 中调用任何函数,它就可以正常工作。一旦我取消注释从库中调用任何函数的任何行,它就会静默失败,甚至没有进入 main()。gdb 没有给出堆栈跟踪,但是说:
During startup program exited with code 0xc0000135.
谷歌搜索并没有发现任何有用的东西。请注意:
- 代码全部使用 C,而不是C++。
- 该代码不包含 __declspec()s 或任何其他 Windows 主义;GCC 文档非常清楚地暗示它们不是必需的,但其他有关创建 DLL 的教程将它们放入。我希望 DLL 像在 Linux 上那样导出所有内容。
- 编译器行是由 cmake 生成的,因为我认为这会使移植更容易,但如果手动构建做正确事情的 Makefile 更容易,我很乐意放弃 cmake。
任何指向正确方向的指针都会有所帮助,包括仅将我指向未过时且不适用于 C++ 的文档。