簡體   English   中英

Python C 模塊擴展版本不兼容嗎?

[英]Is Python C module extension version incompatible?

我在 Python 3.6 中編譯了一個 python c 模塊擴展。 它在 Python 3.6 環境中運行良好,但在 Python 3.7 和 3.8 環境中不起作用,出現錯誤cannot import name 'cygrpc'

我想知道這是預期的行為嗎? 如果是,是什么原因呢。

這取決於擴展的編譯方式以及它使用的 Python C API 接口。 但是是的,通常必須編譯 C 擴展以針對特定版本的 Python 在不知道如何創建擴展模塊的情況下,我認為它需要重新編譯。

通常,Python C API 會在每個版本中更改。 如果該更改破壞了您的擴展程序中的某些內容,自然而然,您必須針對新的 API 接口更新您的擴展程序。 但是,即使您的更改源代碼兼容(不需要更改源代碼來支持新的 Python 版本),也並不意味着編譯后的二進制文件必須兼容。 這就是二進制接口 (ABI) 發揮作用的地方。

另請參閱:穩定的應用程序二進制接口,其中描述了這背后的原因:

原因主要是結構定義的演變,其中添加新字段或更改字段類型可能不會破壞 API,但會破壞 ABI。 因此,每個 Python 版本都需要重新編譯擴展模塊 [...]

還提到了二進制文件跨版本兼容的有限情況:

自 Python 3.2 起,已聲明 API 的一個子集以保證穩定的 ABI。 希望使用此 API(稱為“受限 API”)的擴展模塊需要定義 Py_LIMITED_API。 一些解釋器的細節會從擴展模塊中隱藏起來; 作為回報,構建了一個無需重新編譯即可在任何 3.x 版本 (x>=2) 上運行的模塊。

因此,如果您僅使用穩定 API 的一部分並定義Py_LIMITED_API ,則編譯后的模塊可能無需重新編譯即可跨 Python 版本兼容。

暫無
暫無

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

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