我的程序使用了一些库,这些库包含POSIX函数调用,不能用MinGW编译,我用Qt6来编译MinGW(cygwin或msys2没有Qt6)。所以我需要让我的程序链接到cygwin创建的dll。链接成功,但无法运行。
例如,下面是两个文件a.c
和b.c
:
第一个
我使用cygwin将a.c
编译为a.dll
:
(In cygwin shell)
$ gcc -c a.c -o a.o
$ gcc -shared a.o -o a.dll
$ ldd a.dll
ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x7ff9d5450000)
KERNEL32.DLL => /cygdrive/c/Windows/System32/KERNEL32.DLL (0x7ff9d50f0000)
KERNELBASE.dll => /cygdrive/c/Windows/System32/KERNELBASE.dll (0x7ff9d2e90000)
msvcrt.dll => /cygdrive/c/Windows/System32/msvcrt.dll (0x7ff9d5370000)
cygwin1.dll => /cygdrive/c/Users/notify/Documents/cygwin1.dll (0x180040000)
advapi32.dll => /cygdrive/c/Windows/System32/advapi32.dll (0x7ff9d3b70000)
sechost.dll => /cygdrive/c/Windows/System32/sechost.dll (0x7ff9d3c20000)
RPCRT4.dll => /cygdrive/c/Windows/System32/RPCRT4.dll (0x7ff9d51b0000)
CRYPTBASE.DLL => /cygdrive/c/Windows/SYSTEM32/CRYPTBASE.DLL (0x7ff9d2440000)
bcryptPrimitives.dll => /cygdrive/c/Windows/System32/bcryptPrimitives.dll (0x7ff9d2b50000)
然后我使用MinGW编译了b.c
,并将其链接到a.dll
:
(In MSYS2 MINGW64 shell)
$ gcc -c b.c -o b.o
$ gcc b.o -L. a.dll -o b.exe
$ ldd b.exe
ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x7ff9d5450000)
KERNEL32.DLL => /c/Windows/System32/KERNEL32.DLL (0x7ff9d50f0000)
KERNELBASE.dll => /c/Windows/System32/KERNELBASE.dll (0x7ff9d2e90000)
msvcrt.dll => /c/Windows/System32/msvcrt.dll (0x7ff9d5370000)
a.dll => /c/Users/notify/Documents/a.dll (0x5e4da0000)
cygwin1.dll => /c/Users/notify/Documents/cygwin1.dll (0x180040000)
$ ./b.exe
0 [main] b (1828) C:\Users\notify\Documents\b.exe: *** fatal error - cygheap base mismatch det
ected - 0x180350408/0x18034C408.
This problem is probably due to using incompatible versions of the cygwin DLL.
Search for cygwin1.dll using the Windows Start->Find/Search facility
and delete all but the most recent version. The most recent version *should*
reside in x:\cygwin\bin, where 'x' is the drive on which you have
installed the cygwin distribution. Rebooting is also suggested if you
are unable to find another cygwin DLL.
我怎样才能解决这个问题?
1条答案
按热度按时间wwwo4jvm1#
答案
不要混合MinGW和Cygwin二进制文件!
实际上,您应该将它们视为不同的平台:
它们的标准库是不同的并且彼此不兼容。
这也适用于MSVC,所以也不要将MinGW /MinGW-w 64或Cygwin与MSVC混合。
溶液
使用相同的编译器编译项目的所有组件和依赖项。
一些提示
首选MinGW-w 64
最好尽可能使用MinGW /MinGW-w 64,因为它的目标是本机Windows。
参数:
最后:MinGW-w 64比MinGW更新,所以您应该使用MinGW-w 64而不是MinGW。MinGW-w 64支持32位和64位Windows。您可以通过MSYS 2的软件包管理器
pacman
安装MinGW-w 64,或者您可以从https://winlibs.com/获得独立版本MinGW /MinGW-w 64中缺少POSIX函数
使用MinGW /MinGW-w 64的缺点是缺少一些POSIX函数(例如
fork()
)。因此,您需要将它们替换为Windows替代品。
在
fork()
的情况下,它被用来产生一个守护进程,你可能需要重新设计代码的和平比寻找一个替代fork()
多一点,因为Windows不使用守护进程,但服务。所以你需要为Windows编写一些Windows特定的代码,让你的应用程序作为一个Windows服务运行。您可以使用#ifdef _WIN32
将POSIX代码保留在应用程序中,以便它仍然可以在POSIX平台上编译。对于一些POSIX函数,已经有一些库提供了带有兼容C头文件的Windows替代品,例如:
dlfcn.h
:https://github.com/dlfcn-win32/dlfcn-win32sys/mman.h
/mmap()
/munmap()
:https://github.com/alitrack/mman-win32fork():
https://github.com/i-e-b/win32-fork