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

Odpowiedz Nowy wątek
2015-01-04 23:15
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/ext[...]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ą.


128 postów [25.06.2015r. 21:03]
edytowany 2x, ostatnio: bajos, 2015-01-04 23:16

Pozostało 580 znaków

2015-01-05 00:01
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.


edytowany 1x, ostatnio: Patryk27, 2015-01-05 00:03

Pozostało 580 znaków

2015-01-05 00:09
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.


128 postów [25.06.2015r. 21:03]
edytowany 2x, ostatnio: bajos, 2015-01-05 00:12

Pozostało 580 znaków

2015-01-05 00:12
0

Faktycznie;
Cóż, pozostaje jeszcze to: http://stackoverflow.com/ques[...]ort-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].


edytowany 3x, ostatnio: Patryk27, 2015-01-05 00:12

Pozostało 580 znaków

2015-01-05 00:38
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.


128 postów [25.06.2015r. 21:03]

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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