[英]Linking with cygwin1.dll while building with mingw32?
我希望盡可能少地將Linux C ++應用程序移植到Windows(即根本沒有代碼修改,也沒有全新的構建系統)。
該應用程序主要對SDL
和OpenGL
進行API調用,這些調用都可以在Windows上使用。 但是,它也使用POSIX
功能,如ptys,這阻止我使用mingw32
工具鏈。
Cygwin
,或者更確切地說, cygwin1.dll
,實現了整個POSIX
API,並在內部將其轉換為Win32
。 我知道Cygwin
也有自己的編譯器套件,但根據我的理解,不可能直接調用Win32
或其他Windows庫(如SDL
或OpenGL
)。
因此,我的想法是使用mingw32
構建項目(在大多數發行版中也可以方便地作為交叉編譯器使用),但此外還與cygwin1.dll
鏈接。 然而,我懷疑互聯網上似乎沒有人試過這個,以及Linux上的cygwin編譯器似乎不可用。
所以我的問題是:
許可不是問題。
這不可行。 關鍵問題是C運行時庫(CRT)有兩個不同且不兼容的版本 - Cygwin的GNU庫(glibc)和Microsoft的C運行時。 MinGW工具鏈使用Microsoft CRT,而Cygwin GCC工具鏈使用Cygwin CRT。
這兩個CRT中的每一個都以不同的方式實現。 以malloc()
函數為例。 兩個CRT以不同方式實現malloc()
,可能是通過VirtualAlloc()
從OS分配虛擬內存,然后以自己的方式相應地對其進行分割。 如果你有一個程序將兩個CRT加載到它中並且你從一個CRT調用malloc()
但是然后嘗試在另一個CRT中free()
它會崩潰,因為每個CRT都不知道底層數據結構是如何工作的在另一個。
因此,即使你設法在這里拼湊了一些東西並且沒有錯誤地編譯和鏈接,它仍然會在運行時以“不可能”的方式崩潰,因為這種基本的不兼容性。
現在,什么是在這里做事情的正確方法? 您需要決定要使用哪個CRT。 Microsoft CRT不支持許多POSIX功能,因此如果您不想重寫代碼以避免所有缺少POSIX功能,則必須使用Cygwin CRT,並且必須將它用於項目中的所有代碼(所有源文件,所有靜態庫,所有DLL等)。
您對Win32的理解是錯誤的 - 您可以從Cygwin程序調用原始Win32 API。 Cygwin GCC工具鏈甚至還帶有自己的<windows.h>
頭文件。 對調用CreateFile
, VirtualAlloc
等函數沒有任何限制。
對於您正在使用的其他庫,例如SDL和OpenGL,您需要針對您所針對的相同CRT編譯的那些庫的版本。 如果你有庫的源代碼,那么你可以自己編譯它們。
以下是為Cygwin編譯SDL的說明 。 對於OpenGL,您可以通過Cygwin設置安裝一堆軟件包來獲取OpenGL頭文件和庫,例如libEGL-devel
, libGL-devel
, libGLU-devel
, libglut-devel
和libGLw-devel
軟件包。
我強烈建議不要這樣做。 在鏈接階段,最重要的是在運行時,您肯定會遇到二進制不兼容問題和許多其他細微問題。 每個工具鏈都有其用途,因此請更好地使用符合您要求的工具。
對我來說兩種方法看起來都很好 Cygwin的翻譯開銷實際上是最小的,並且您不必為您的應用程序分發整個Cygwin,而只需要運行時DLL。 不過,就個人而言,我認為現代跨平台應用程序應該很難真正實現跨平台,而不是直接使用像POSIX這樣的低級API,因為這實際上是應用程序的一個缺陷,它首先聲稱是跨越平台。 感謝上帝,今天我們有大量現代化和高質量的圖書館來幫助我們。 例如,在我的項目中,我總是堅持第一種方法,到目前為止我不得不承認它總是可行的,但有時候只需要一些你不應該害怕的麻煩,因為它肯定會在未來得到回報。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.