Python (embedded w C++) nie ładuje modułu

0

Witajcie,

Chciałem odpalić def main(input) napisaną w Pythonie z C++. Opierałem się na tej oficjalnej stronie https://docs.python.org/3/extending/embedding.html#pure-embedding . Napisałem taki kod:

#include <iostream>
#include <string>

#include <Python.h>

#include "main.hpp"
#include "cmd.hpp"
#include "cmdDataReader.hpp"

int main(int argc, char* argv[])
{
	CmdParser parser;
	parser.addArg("-f");
	parser.addArg("-out");
	parser.addArg("-in");
	parser.addArg("-h");
	parser.parseCmd(argc, argv);

	CmdDataReader reader;
	std::string format = reader.returnArg(parser, "-f");
	std::string input = reader.returnArg(parser, "-in");

	Py_Initialize();

	PyObject* ModuleName = PyBytes_FromString(format.c_str());
	PyObject* Module = PyImport_Import(ModuleName);
	Py_DECREF(ModuleName);

	if (Module != NULL)
	{
		PyObject* MainFunc = PyObject_GetAttrString(Module, "main");

		if (MainFunc && PyCallable_Check(MainFunc))
		{
			PyObject* Args = PyTuple_New(1);
			PyObject* Value = PyBytes_FromString(input.c_str());
			
			PyTuple_SetItem(Args,0,Value);

			Value = PyObject_CallObject(MainFunc, Args);
			Py_DECREF(Args);

			if (Value != NULL)
			{
				std::cout << PyBytes_AsString(Value);
			}
			else
			{
				Py_DECREF(Value);
				return 1;
			}
		}
		else
		{
			Py_DECREF(MainFunc);
			return 1;
		}
	}
	else
	{
		Py_XDECREF(Module);
		return 1;
	}

	Py_Finalize();
    return 0;
}

Przez debugger i std::cout sprawdziłem, że program wchodzi w else tam gdzie jest Py_XDECREF(Module) czyli, że ładowanie modułu nie zadziałało. Piszę na forum bo jeśli nawet kod z oficjalnej strony nie działa to coś nie tak. Linkuje bibliotekę python3.lib. W folderze z .exe mam plik obj.py i python3.dll. Program uruchamiam w cmd z dodatkowymi parametrami -f obj -in test
Plik obj.py zawiera:

def main(input):
	print(input)
	return input

PS. Klasy CmdParser i CmdDataReader działają.

0

Co zwraca format.c_str()?
Bo wydaje mi się, że w ModuleName powinno być obj.py, a nie samo obj, jeżeli to jest zwracane przez kod powyżej.

0

format.c_str() zwraca "obj" (bez cudzysłowu, tutaj jako cytat). Jak czytałem gdzies o modułach to pisało, że nazwę podaje się bez bez rozszerzenia (tak jak w Pythonie robi się to przez import ...) tymbardziej, że w tym linku z https://docs.python.org nie ma dodawania końcówki .py ani w cmd też nie było dodane.

0

Faktycznie;
Cóż, pozostaje jeszcze to: http://stackoverflow.com/questions/17532371/pyimport-import-fails-returns-null

I have resolved this issue by setting PYTHONPATH to pwd. Also module name (without .py) should be set for argv[1].

0

Zrobiłem inaczej. Wyświetliłem PyErr_Print() okazało się, że nazwa modułu to musi być PyUnicode_FromString() zamiast PyBytes_FromString(). Teraz jest problem gdy chce wyświetlić return value. W Pythonie zwracam w funkcji to co wcześniej przekazałem do tej funkcji jako PyUnicode tylko nie wiem jak PyUnicode zamienić na char bo nie ma takiej funkcji. Jak użyje PyBytes_AsString(zmienna_z_returnvalue) to program się crashuje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1