[英]How to let MinGW compiled program link to dll built by cygwin?
我的程序使用了一些包含 POSIX function 調用的庫,並且無法使用 MinGW 進行編譯,我將 Qt6 用於 MinGW(沒有 Qt6 用於 cygwin 或 msys2)。 所以我需要讓我的程序鏈接到cygwin構建的dll。 鏈接成功,但無法運行。
例如,這里有兩個文件a.c
和b.c
:
/* a.c */
int a() {
return 1;
}
/* b.c */
extern int a();
int main() {
return a();
}
我使用 cygwin 將a.dll
a.c
(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.
我怎么解決這個問題?
不要混合使用 MinGW 和 Cygwin 二進制文件!
事實上,您應該將它們視為不同的平台:
它們的標准庫不同且彼此不兼容。
這也適用於 MSVC,因此也不要將 MinGW / MinGW-w64 或 Cygwin 與 MSVC 混合使用。
使用相同的編譯器編譯項目的所有組件和依賴項。
最好盡可能使用 MinGW / MinGW-w64,因為它針對本機 Windows。
Arguments:
最后:MinGW-w64 比 MinGW 更新,因此您應該使用 MinGW-w64 而不是 MinGW。 MinGW-w64 支持 32 位和 64 位 Windows。您可以通過 MSYS2 的 package 管理器pacman
安裝 MinGW-w64,或者您可以從https://winlibs.com/獲得獨立構建
使用 MinGW / MinGW-w64 的缺點是缺少一些 POSIX 函數(例如fork()
)。
所以你需要用他們的 Windows 替代品替換它們。
在fork()
用於生成守護進程的情況下,您可能需要重新設計代碼的和平,而不是為fork()
尋找替代方案,因為 Windows 不使用守護進程,而是使用服務。 因此,您需要為 Windows 編寫一些特定於 Windows 的代碼,以允許您的應用程序作為 Windows 服務運行。 您可以使用#ifdef _WIN32
將您的 POSIX 代碼保留在您的應用程序中,這樣它仍然可以在 POSIX 平台上編譯。
對於某些 POSIX 函數,已經有一些庫提供 Windows 替代品和兼容的 C header,例如:
dlfcn.h
: https://github.com/dlfcn-win32/dlfcn-win32sys/mman.h
/ mmap()
/ munmap()
: https://github.com/alitrack/mman-win32fork():
https://github.com/ieb/win32-fork
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.