7

Python拡張モジュールは単なるダイナミックライブラリなので、Python拡張を別の拡張に動的にリンクできると思います。問題はWindowsにあります。Python拡張機能にはの.pyd代わりに拡張機能が与えられている.dllため、セットアップスクリプトを実行するときにdistutilsをそれらにリンクさせることができません。(Python拡張機能はファイル拡張子を使用するため、これはUNIXでは問題ではないと思い.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.o)を拡張機能のオプションに渡すことでこの問題を解決しました(これは、ですべてのシンボルのプロトタイプを定義した場合にのみ機能します):fooextra_objectsfoobar

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"])

これは文句なしにコンパイルされましたが、いくつかのシンボルにいくつかの問題がありました(具体的には、で再定義されたように見えるいくつかPyTypeObjectfooグローバルがありましたbar。両方のモジュールのが同じ定義を参照する必要がありPyTypeObjectます)。

編集2:それで、私は問題を選び出しました。インポートライブラリをビルドしてリンクした後、関数シンボルは正しくエクスポートされていましたが、PyTypeObjectsが再宣言されていました。にがあったと仮定PyTypeOject Foo_Typefooます。私はそれをで宣言しました、それはとの両方にfoo.h含まれていました:foo.cbar.c

PyTypeObject Foo_Type;

私はそれを取り出して、これを上部近くに置きましたfoo.c

PyTypeObject __declspec(dllexport) Foo_Type;

そしてこれは上部近くにありbar.cます:

PyTypeObject __declspec(dllimport) Foo_Type;

これで問題は解決しました。次に、両方fooでFoo_Typeを使用でき、Foo_Typebarの同じ定義を参照しました。問題は、これがWindows以外のシステムでは機能しないことです。__declspecsを取り出すだけで、他のシステムでも問題なく動作すると思います。

4

2 に答える 2

2

通常のPythonインポートメカニズムを使用している場合は、他の拡張機能に対してリンクする必要はありません。他の拡張機能内で関数を呼び出している場合、おそらくヘッダーファイルを保持しているため、DLLに対してリンクする前に、DLLからインポートライブラリを生成する必要があります。

于 2010-07-17T04:51:32.623 に答える
-3
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
    ]
);

から: http: //pyd.readthedocs.io/en/latest/distutils.html

于 2017-10-20T06:00:18.897 に答える