我已经阅读了这里的所有内容以及我在网上可以找到的有关执行此操作的所有内容,但这些信息已经过时、矛盾或不适用。我有一个非常简单的 C 库,我将其编译为 Linux 中的共享库,并且一切都运行良好。我想将其移植到 Windows DLL。自 20 世纪 90 年代以来,我就没有编写过 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++ 的文档。
您可以在 https://github.com/brechtsanders/ci-test 找到 C 语言库的最小示例,其中说明了如何使用 Makefile 和 CMake,并且代码是跨平台的(相同的代码还可以构建在 Linux 和 macOS 上)