Ich habe ein reines C-Modul für Python und möchte es mit dem python -m modulename
-Ansatz aufrufen können. Dies funktioniert gut mit Modulen, die in Python implementiert sind, und eine offensichtliche Problemumgehung besteht darin, eine zusätzliche Datei für diesen Zweck hinzuzufügen. Allerdings möchte ich wirklich Dinge auf meine einzige verteilte Binärdatei beschränken und keine zweite Datei nur für diese Problemumgehung hinzufügen.
Es ist mir egal, wie hacky die Lösung ist.
Wenn Sie versuchen, ein C-Modul mit -m zu verwenden, erhalten Sie eine Fehlermeldung No code object available for <modulename>
.
-m
Implementierung ist in runpy._run_module_as_main
. Sein Wesen ist:
Ein kompiliertes Modul hat kein "code object", daher wird die erste Anweisung mit ImportError("No code object available for <module>")
fehlschlagen. Sie müssen runpy - speziell _get_module_details
- erweitern, damit es für ein kompiliertes Modul funktioniert. Ich schlage vor, ein Codeobjekt zurückzugeben, das aus dem oben genannten "import mod; mod.main()"
erstellt wurde:
(Python 2.6.1)
(Update: Fehler in Formatzeichenfolge behoben)
Jetzt ...
%Vor%Dies funktioniert immer noch nicht für eingebaute Module. Auch hier müssen Sie eine Vorstellung von "Hauptcodeeinheit" für sie erfinden.
Aktualisierung:
Ich habe die von _get_module_details
aufgerufenen Interna durchgesehen und kann mit Zuversicht sagen, dass sie nicht einmal versuchen, ein Code-Objekt von einem anderen Modul als imp.PY_SOURCE
abzurufen, imp.PY_COMPILED
oder imp.PKG_DIRECTORY
. Sie müssen also diese Maschine auf diese oder eine andere Art patchen, damit -m
funktioniert. Python schlägt fehl bevor etwas von deinem Modul abruft (es wird nicht einmal überprüft, ob die DLL ein gültiges Modul ist), also kannst du nichts machen, indem du es in einem speziellen Build erstellst Weg.
Erlaubt Ihre Anforderung der einzelnen verteilten Binärdatei die Verwendung eines Eies? Wenn ja, könnten Sie Ihr Modul mit einem __main__.py
mit Ihrem Aufrufcode und dem üblichen __init__.py
...
Wenn Sie wirklich fest sind, könnten Sie vielleicht pkgutil.ImpLoader.get_code
erweitern, um etwas für C-Module zurückzugeben (z. B. eine spezielle __code__
-Funktion). Um das zu tun, müssen Sie es in der Python-Quelle ändern. Selbst dann verwendet pkgutil
exec
, um den Codeblock auszuführen, also müsste es sowieso Python-Code sein.
TL; DR: Ich glaube, du bist souchred. Während Python-Module Code auf globaler Ebene haben, der zum Zeitpunkt des Imports ausgeführt wird, sind dies bei C-Modulen nicht der Fall; Sie sind meist nur ein Namespace. Daher macht das Ausführen eines C-Moduls aus konzeptioneller Sicht keinen Sinn. Sie benötigen echten Python-Code, um die Aktion zu steuern.
Ich denke, dass Sie damit beginnen müssen, eine separate Datei in Python zu erstellen und die Option -m zum Laufen zu bringen. Dann wandeln Sie diese Python-Datei in ein Code-Objekt um und integrieren Sie es so in Ihre Binärdatei, dass es weiter funktioniert.
Nachsehen von setuptools in PyPi, lade das .egg runter und schaue dir die Datei an. Sie werden sehen, dass die ersten paar Bytes ein Python-Skript enthalten, gefolgt von einem .ZIP-Datei-Bytestream. Etwas Ähnliches mag für dich funktionieren.
Tags und Links python