Python擴展模塊只是動態庫,所以我認爲可以將Python擴展動態鏈接到另一個擴展。問題出在Windows上,Python擴展名被賦予了.pyd
擴展名而不是.dll
,所以當我運行安裝腳本時,我無法將distutils鏈接到它們。 (我不認爲這是UNIX上的問題,因爲Python擴展使用.so
文件擴展名。)將Python擴展(.pyd)動態鏈接到另一個擴展
假設我有一個擴展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.o
)時foo
被編譯爲擴展中的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"])
這編譯投訴,但有一些問題與一些符號(具體來說,我有PyTypeObject
s在foo
幾個似乎在bar
重新定義。我需要PyTypeObject
這兩個模塊中的s都指的是相同的定義)。
編輯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
s,它會在其他系統上正常工作。
這些擴展模塊的兩個是我的項目的一部分,所以我想使用Python導入機制,而不是它們之間的鏈接。不過,我很新,所以我不太確定如何生成導入庫。你能對此有所瞭解嗎? – 2010-07-17 05:02:49