PyImport_ImportModule

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Hallo,

ich habe Python 3.11 für alle User auf Windows 10 installiert. Nun versuche ich seit 2 Tagen, über mein C++-Programm und PyImport_ImportModule ein eigenes Modul zu laden. Der Code sieht im wesentlichen so aus:

Py_Initialize();

PyRun_SimpleString(
"import os, sys \n"
"sys.path.append(os.getcwd()) \n"
);

/*PyObject* sysmodule = PyImport_ImportModule("sys");
PyObject* syspath = PyObject_GetAttrString(sysmodule, "path");
PyList_Append(syspath, PyUnicode_FromWideChar(_T("."),1));
Py_DECREF(syspath);
Py_DECREF(sysmodule);*/

//PyRun_SimpleString("import sys\n sys.path.append(\"A:/DATA/VisualStudioProjects/Projects/VS2022/Pythonserver/x64/Debug\")\n");
PyObject * pModule = PyImport_ImportModule("Translation");


Leider ist pModule immer 0. Ich habe inzwischen alle Hinweise, die ich finden konnte ausprobiert. Nichts funktioniert. Interessanterweise funktioniert das Laden der Standard-Pythonmodule aus C:\Program Files\Python311\Lib. Also habe ich mein Modul auch dorthin kopiert. Das funktioniert aber nicht.
Übrigens liefert PyErr_Print(); nichts zurück. Es wird absolut nichts "geprintet".

Danke und Grüße,
Thomas
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@antipas5@msn.com: Ich kann das Problem nicht nachvollziehen. Folgendes Programm funktioniert bei mir:

Code: Alles auswählen

#include <Python.h>

int main()
{
    Py_Initialize();
    PyRun_SimpleString("import sys; sys.path.append('.')\n");
    PyObject * pModule = PyImport_ImportModule("Translation");
    if (pModule) {
        Py_DECREF(pModule);
    } else {
        PyErr_Print();
    }
    return 0;
}
Wenn es im Arbeitsverzeichnis *keine* `Translation.py` gibt, wird die Ausnahme ausgegeben:

Code: Alles auswählen

$ ./a.out
ModuleNotFoundError: No module named 'Translation'
Wenn es eine gibt, mit dem Inhalt ``print("Imported", __file__)``, dann wird das auch ausgegeben:

Code: Alles auswählen

$ ./a.out 
Imported /home/bj/./Translation.py
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Ich führe den Code aktuell im Visual Studio Debugger aus. Ich hatte zwischenzeitlich die Vermutung, dass das Working Dir das Verzeichnis ist, in dem devenv.exe liegt. Also habe ich das Modul dorthin kopiert. Das hat aber auch nix genützt und erklärt auch nicht, weshalb die Standardmodule problemlos importiert werden. Es würde mir schon weiterhelfen, wenn es eine API-Funktion gäbe, um os.getcwd() aufzurufen. Das scheint es aber nicht zu geben. Ich verstehe auch nicht, weshalb man keinen voll qualifizierten Pfad angeben kann.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst doch mit PyRun_SimpleString ein import gefolgt vom print(os.getcwd()) etc machen.
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Ja, das mache ich auch. Aber ich kann das Ergebnis nicht sehen, weil der print einfach gar nix bewirkt. Über eine API-Funktion könnte ich im C++ ein Message-Popup rauswerfen.-
Gibt es irgendsowas wie ein globales Verzeichnis, in dem die Standardmodule drinstehen? Oder gibt es irgendeine andere Erklärung, weshalb das Procedere für Standardmodule geht, bei eigenen aber nicht.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Unter Windows sind viele Module auch „frozen“, also fest einkompiliert. Das spielt da auch rein.

Mit einem debugger kann man natürlich auch mal die internen Strukturen des Interpreters absuchen, ob man da was findet.

Und du kannst natürlich auch die Liste sys.path über die C-API elementweise auslesen & die String Objekte in C strings wandeln & ausgeben.
Benutzeravatar
__blackjack__
User
Beiträge: 13069
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@antipas5@msn.com: Warum willst Du `os.getcwd()` aufrufen? Der Prozess ist Dein C++-Programm, da brauchst Du keine *Python*-Funktion aufrufen um das aktuelle Arbeitsverzeichnis zu ermitteln, da kannst Du auch einfach ``std::filesystem::current_path`` verwenden.

Module aus der Standardbibliothek können importiert werden, weil deren Pfade offenbar in ``sys.path`` liegen. Und natürlich kann man auch einen vollen Pfad angeben. Und man kann auch ``print()`` ausführen, ich weiss nicht ob es Sinn macht weiter mit Importen zu experimentieren wenn nicht mal so etwas simples wie `print()` funktioniert.

Erster Kandidat wäre da mal die IDE raus zu nehmen und das mal freistehend auszuprobieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Habe inzwischen eine Konsolen-App gemacht, und von der Befehlszeile aus ausgeführt. Das ist die Ausgabe:

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

https://numpy.org/devdocs/user/troubles ... error.html

Please note and check the following:

* The Python version is: Python3.11 from "C:\Users\Thomas\source\repos\PythonImport\x64\Release\PythonImport.exe"
* The NumPy version is: "1.26.2"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: No module named 'numpy.core._multiarray_umath'


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\site-packages\numpy\__init__.py", line 149, in <module>
raise ImportError(msg) from e
ImportError: Error importing numpy: you should not try to import numpy from
its source directory; please exit the numpy source tree, and relaunch
your python interpreter from there.


Das Problem besteht also offenbar darin, dass numpy nicht importiert werden kann. Leider kann ich mit dieser Aussage nichts anfangen:

Error importing numpy: you should not try to import numpy from
its source directory;
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Benutzt du denn numpy? Und die Fehlermeldung besagt, dass du numpy "richtig" installiert haben musst, und nicht aus versehen aus einem checkout der Quellen oder so importieren darfst.
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Ich benutze numpy nicht direkt, aber das Paket, das ich importiere, benutzt numpy. Ich kann alles importieren mit dem obigen Verfahren, was nicht irgendwie numpy enthält.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich wuerde den Brotkrumen folgen, und schauen, was denn an der Stelle in numpy/__init__.py Zeile 149 in die Hose geht. Der Pfad da sieht ja eigentlich gut aus, also musst du rausfinden, warum der denkt, es waere anders.
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

__NUMPY_SETUP__ ist nicht definiert. Was hat es denn damit auf sich?
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Keine Ahnung. Du musst schauen, wo das definiert wird unter normalen Umständen. Und warum es bei dir nicht definiert ist.
__deets__
User
Beiträge: 14522
Registriert: Mittwoch 14. Oktober 2015, 14:29

Weil ich gerade mal etwas Zeit hatte: https://github.com/numpy/numpy/blob/d4a ... __.py#L103 zeigt, dass es genau *NICHT* definiert sein darf. Kann es sein, dass du da die Logik verkehrt hast?
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Gut, dass wir jetzt wissen, dass numpy involviert ist. Das muss man nämlich extra initialisieren:

Code: Alles auswählen

#include "Python.h"
#include "numpy/arrayobject.h"

int main(int argc, char **argv) {
   Py_Initialize();
   import_array();
   ...
   Py_Finalize();
   return 0;
}
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Ich sehe hier keine "extra Initialisierung". Das "import_array" funktioniert nicht. Da knallt es sofort:


Could not find platform dependent libraries <exec_prefix>
Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\site-packages\numpy\core\__init__.py", line 24, in <module>
from . import multiarray
File "C:\Program Files\Python311\Lib\site-packages\numpy\core\multiarray.py", line 10, in <module>
from . import overrides
File "C:\Program Files\Python311\Lib\site-packages\numpy\core\overrides.py", line 8, in <module>
from numpy.core._multiarray_umath import (
ModuleNotFoundError: No module named 'numpy.core._multiarray_umath'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\site-packages\numpy\__init__.py", line 144, in <module>
from numpy.__config__ import show as show_config
File "C:\Program Files\Python311\Lib\site-packages\numpy\__config__.py", line 4, in <module>
from numpy.core._multiarray_umath import (
File "C:\Program Files\Python311\Lib\site-packages\numpy\core\__init__.py", line 50, in <module>
raise ImportError(msg)
ImportError:

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

https://numpy.org/devdocs/user/troubles ... error.html

Please note and check the following:

* The Python version is: Python3.11 from "C:\Users\Thomas\source\repos\PythonImport\x64\Release\PythonImport.exe"
* The NumPy version is: "1.26.3"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: No module named 'numpy.core._multiarray_umath'


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\site-packages\numpy\__init__.py", line 149, in <module>
raise ImportError(msg) from e
ImportError: Error importing numpy: you should not try to import numpy from
its source directory; please exit the numpy source tree, and relaunch
your python interpreter from there.


Das ist übrigens genau der gleiche Fehler, der sonst beim Import von numpy entsteht. Das ist für mich auch nicht plausibel, dass man Teile des Moduls importieren muss, bevor man das Modul importiert. Mindestens ist das keineswegs offensichtlich.-

Wenn man in __init__.py in Zeile 135 __NUMPY_SETUP__ = True setzt, funktioniert der Import von numpy. Natürlich funktioniert der Import des verwendenden Moduls trotzdem nicht.
Das ist schon recht optimistisch, dieses API als API zu bezeichnen.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Kannst Du denn numpy importieren, wenn Du ganz normal Python benutzt?
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Ja.
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

Und ist es diese Pythonversion mit dieser numpy-Version?
antipas5@msn.com
User
Beiträge: 11
Registriert: Freitag 29. Dezember 2023, 21:43

Ich habe 3 Mal Python 311 neu installiert.
Antworten