簡體   English   中英

為什么不同語言的二進制文件彼此不兼容? 你如何使它們兼容?

[英]Why aren't binaries of different languages compatible with each other? How do you make them compatible?

swift 應用程序會將其動態框架轉換為二進制文件。 一旦某些東西是二進制的,那么它就不再是 Swift/Ruby/Python 等。它是機器代碼。

Python 二進制文件也會發生同樣的事情。 那么,為什么機器代碼不是開箱即用的相互兼容的呢?

只是需要一個簡單的映射來將一種語言連接到另一種語言嗎?

就像如果我需要使用從 Swift 語言創建的二進制文件到基於 Python 的應用程序,那么我是否需要將 Swift 標頭公開給 Python 才能工作? 還是需要其他東西?

我假設您是在談論用一種語言調用用另一種語言編譯的庫。

在匯編語言級別,有一些標准( ABI ,用於應用程序二進制接口)定義了 function 參數如何在寄存器中傳遞、如何返回值、堆棧的行為等。ABI 依賴於體系結構和操作系統。 通常在庫中導出的任何 function 都將遵循 ABI。

很明顯,ABI 基本上期望函數使用 C 語言 model:單個返回值、每個參數的定義明確的數據類型 function 以及返回值、使用指針的可能性等。

一旦您轉向更高級別的語言,問題就會開始出現。 C++ 已經引入了復雜性:而 C function 的名稱在匯編中是相同的(通常在前面加上一個_字符),在 C++ function 中名稱必須編碼數據類型,因為有可能重載具有相同名稱但不同參數的函數。 因此,名稱必須被破壞和分解——這就是為什么 C function 的原型必須在 C++ 中聲明為extern "C" 。然后是類( this指針、vtables)、名稱空間等問題,這使事情進一步復雜化。

然后你有像 Python 這樣的動態類型語言。事實上,在匯編語言級別沒有dynamic typing這樣的東西:機器語言中的指令編碼(即二進制代碼,因為它們在執行時被 CPU 讀取)隱式確定是否您正在使用 integer 或浮點或 SIMD 指令(以及操作數的寬度),這也決定了訪問哪些不同的寄存器組。 盡管該語言使動態類型對您透明,但在匯編代碼級別,解釋器/JIT/編譯器必須以某種方式解決它們,因為最終必須告訴 CPU 確切地操作什么數據類型。

這就是為什么您不能直接從 Python 調用 C function(或一般任何庫函數)的原因——與可以忽略其參數類型的純 Python function 不同,庫函數必須知道每個參數的確切類型和返回類型。 因此,您必須為 Python 使用類似ctypes的東西,明確指定需要調用的每個 function 的相關類型——在某種程度上,這類似於通常在 C 標頭中找到的 function 原型。 可以在 C 中編寫可直接從 Python 調用的函數(並且在這種情況下,基本上僅從 Python 調用),但您將不得不跳過幾個環節

至於您感興趣的特定語言配對(Python/Swift),在 Swift 論壇(從那里鏈接的這個帖子,可能也很有趣。閱讀該帖子,似乎有目前有兩個可行的解決方案:首先,使用@_cdecl屬性(官方不支持)制作一個 C function,然后使用ctypes從 Python 調用它。但是第二個顯然更有希望的是使用@objc中的 objc 屬性,並在 Python 中使用PyObjC 。我認為這將允許使用 Swift 的一些高級功能,至少是那些與 Objective-C 提供的功能相交的功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM