[英]Dynamically Linking Python Extension (.pyd) to Another Extension
Python擴展模塊只是動態庫,因此我假設可以將Python擴展動態鏈接到另一個。 問題是在Windows上,Python Extensions被賦予.pyd
擴展名而不是.dll
,所以當我運行安裝腳本時,我無法讓distutils鏈接到它們。 (我不認為這是UNIX上的問題,因為Python擴展使用.so
文件擴展名。)
假設我有一個擴展名bar.pyd
,需要鏈接到foo.pyd
。 基本上,我在安裝腳本中所做的是:
from distutils.core import setup, Extension
foo = Extension("foo", sources=["foo.c"])
bar = Extension("bar", libraries=["foo"], sources=["bar.c"])
setup(ext_modules=[foo, bar])
到目前為止,這是行不通的。 這甚至可能嗎? 我認為是,但我無法在網上找到任何東西。 我在Windows上使用MinGW,但我希望這可以使用不同的MSVC ++以及其他系統。
編輯:以前,我通過將編譯foo
時創建的目標文件( foo.o
)傳遞給擴展中的extra_objects
選項解決了這個問題(這只有在我在bar
定義所有foo
符號的原型時才有效):
bar = Extension("bar", sources=["bar.c"], extra_objects=["build/.../foo.o"]
這似乎不是正確的解決方案,但它確實有效。 我不明白動態鏈接,所以這可能是正確的方法。 但是感覺非常錯誤。
然后,我嘗試將一些顯式參數傳遞給gcc,以使其編譯導入庫:
foo = Extension("foo", sources=["foo.c"], extra_compile_args=["-Wl,--out-implib,foo.lib,--export-all-symbols"])
然后我將bar
鏈接到新的導入庫:
bar = Extension("bar", libraries=["foo"], sources=["bar.c"])
這個編譯沒有抱怨,但是有一些符號存在一些問題(具體來說,我在foo
中有一些全局PyTypeObject
似乎在bar
重新定義。我需要兩個模塊中的PyTypeObject
引用相同的定義。) 。
編輯2:所以,我挑出了問題。 在我構建並鏈接到導入庫之后,函數符號正確導出,但PyTypeObject
正在重新聲明。 假設foo
有一個PyTypeOject Foo_Type
。 我在foo.h
聲明了它,它包含在foo.c
和bar.c
:
PyTypeObject Foo_Type;
我拿出來,把它放在foo.c
的頂部附近:
PyTypeObject __declspec(dllexport) Foo_Type;
這靠近bar.c
的頂部:
PyTypeObject __declspec(dllimport) Foo_Type;
這解決了問題。 然后我可以在foo
和bar
使用Foo_Type,它引用了與Foo_Type相同的定義。 問題是,這不適用於非Windows系統。 我假設如果我只是把__declspec
拿出來,它在其他系統上工作正常。
如果您使用的是普通的Python 導入機制,則無需鏈接其他擴展。 如果您在另一個擴展中調用函數,可能是因為您已經保留了頭文件,那么您需要先從DLL生成一個導入庫,然后才能鏈接它。
from distutils.core import Extension as cExtension
from pyd.support import setup, Extension
module1 = Extension("x", sources = ['xclass.c'])
module2 = Extension("y", sources = ['hello.d'], build_deimos=True)
setup(
name = "x",
version = '1.0',
description = "eat a taco",
ext_modules = [
module1,
module2
]
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.