Модули расширения Python - это просто динамические библиотеки, поэтому я предполагаю, что можно динамически связать расширение Python с другим.Проблема в Windows Python Расширения имеют расширение .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])
Пока это не работает.Это вообще возможно?Я предполагаю, что это так, но я не смог ничего найти в Интернете.Я использую MinGW в Windows, но мне бы хотелось, чтобы это работало с другими MSVC ++ и другими системами.
Редактировать: Ранее я решил эту проблему, передав объектный файл(foo.o
), созданный, когда foo
был скомпилирован с параметром extra_objects
в расширении (это работало бы, только если я определил прототипы всех символов foo
в bar
):
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 в обоих модулях относились к одному и тому же определению.).
Edit 2: Итак, я выделил проблему.Символы функций экспортировались корректно после того, как я собрал и связал их с библиотеками импорта, но PyTypeObject
были повторно объявлены.Предположим, что было PyTypeOject Foo_Type
в foo
.Я объявил это в foo.h
, который был включен как в foo.c
, так и bar.c
:
PyTypeObject Foo_Type;
Я вынул его и поместил в верхнюю часть foo.c
:
PyTypeObject __declspec(dllexport) Foo_Type;
и это в верхней части bar.c
:
PyTypeObject __declspec(dllimport) Foo_Type;
Это решило проблему.Затем я мог бы использовать Foo_Type как в foo
, так и bar
, и он ссылался на одно и то же определение Foo_Type.Проблема в том, что это не сработает в системах, отличных от Windows.Я предполагаю, что если я просто возьму __declspec
s, он будет работать нормально на других системах.