Les modules d'extension Python ne sont que des bibliothèques dynamiques. Je suppose donc qu'il est possible de lier dynamiquement une extension Python à une autre. Le problème est sur Windows Python extensions sont donnés l'extension .pyd
au lieu de .dll
, donc je ne peux pas obtenir distutils à lier à eux lorsque je cours le script d'installation. (Je ne pense pas que ce soit un problème sous UNIX, car les extensions Python utilisent l'extension de fichier .so
.)Lier dynamiquement une extension Python (.pyd) à une autre extension
Supposons que j'ai une extension bar.pyd
qui doit créer un lien vers foo.pyd
. Au fond, ce que je faisais dans le script de configuration a été:
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])
Jusqu'à présent, cela ne fonctionne pas. Est-ce seulement possible? Je suppose que c'est le cas, mais je n'ai pas été en mesure de trouver quelque chose en ligne. J'utilise MinGW sous Windows, mais j'aimerais que cela fonctionne avec MSVC++ différent et sur d'autres systèmes.
Edit: Auparavant, je résolu ce problème en passant le fichier objet (foo.o
) créé lorsque foo
a été compilé à l'option extra_objects
dans l'extension (cela ne fonctionnera que si je définissais des prototypes de tous foo
symboles bar
) :
bar = Extension("bar", sources=["bar.c"], extra_objects=["build/.../foo.o"]
Cela ne semble pas être la bonne solution, mais cela a fonctionné. Je ne comprends pas bien le lien dynamique, alors c'est peut-être la bonne façon de le faire. C'est très mal, cependant.
Ensuite, j'ai essayé passer quelques arguments explicites à gcc pour le compiler une bibliothèque d'importation:
foo = Extension("foo", sources=["foo.c"], extra_compile_args=["-Wl,--out-implib,foo.lib,--export-all-symbols"])
Et puis je lié bar
à la nouvelle bibliothèque d'importation:
bar = Extension("bar", libraries=["foo"], sources=["bar.c"])
Cette compilation sans plainte, mais il y avait quelques problèmes avec certains des symboles (en particulier, j'ai eu quelques PyTypeObject
s dans foo
s qui ont semblé être redéfini en bar
J'ai besoin de PyTypeObject
s dans les deux modules se réfèrent à la même définition.).
Édition 2: Donc, j'ai isolé le problème. Les symboles de fonction exportaient correctement après avoir construit et lié les bibliothèques d'importation, mais les PyTypeObject
étaient redéclarés. Supposons qu'il y ait eu un PyTypeOject Foo_Type
dans foo
. Je déclarais dans foo.h
, qui a été inclus dans les deux foo.c
et bar.c
:
PyTypeObject Foo_Type;
J'ai pris que dehors, et mettre ce en haut de foo.c
:
PyTypeObject __declspec(dllexport) Foo_Type;
et ce en haut de bar.c
:
PyTypeObject __declspec(dllimport) Foo_Type;
Cela a résolu le problème. Je pourrais alors utiliser Foo_Type à la fois foo
et bar
et il se référait à la même définition de Foo_Type. Le problème est, cela ne va pas fonctionner sur les systèmes non-Windows. Je suppose que si je prends juste le __declspec
, il fonctionnera bien sur d'autres systèmes.
Ces deux modules d'extension font partie de mon projet, je voudrais relier entre eux au lieu d'utiliser les mécanismes d'importation Python. Je suis assez nouveau à ce sujet, donc, je ne suis pas tout à fait sûr de savoir comment générer la bibliothèque d'importation. Pouvez-vous nous éclairer à ce sujet? –