c++python-3.xpython-embedding

Stuck at PyObject_GetAttrString() : How to get my Python function script from my C++ code


My problem is that I cannot get a function from my Python script on my C++ script.

I use Python/C API and my IDE is VScode. When i run the code, it stop at the specific line calling PyObject_GetAttrString()

This line into the task.json of VScode is used to build my code : g++ -IC:/Users/Martin/AppData/Local/Programs/Python/Python37-32/libs/python37.a main.cpp -LC:/Users/Martin/AppData/Local/Programs/Python/Python37-32/libs -lpython37

And this line to run it: .\a.exe (.exe auto created by VScode)

It's the first time I tried to use Python code through C++ code like that. I've already searched in forums and on another topics on stackoverflow, but after all I tried I don't get it. Here is the code:

C++ code : main.cpp (which I execute)

#include <iostream>
#include "C:/Users/Martin/AppData/Local/Programs/Python/Python37-32/include/Python.h"
using namespace std;

int main ()
{
    cout << "Start \n";
    
    Py_Initialize();
    cout << "2\n";  PyObject* my_module = PyImport_ImportModule("mat");
    cout << "3\n";  PyObject* my_function = PyObject_GetAttrString(my_module,"getfive");
    cout << "4\n";  PyObject* my_result = PyObject_CallObject(my_function,NULL);
    cout << "5\n";  double result = PyFloat_AsDouble(my_result);
    cout << "6\n";  printf("My result is :  %f",result);
    cout << "7\n";
    Py_Finalize();

    return 0;
}

Python code : mat.py

def getfive():
    print "python say 5 !"
    return 5

def speak():
    print "speak"

Output I except to have:

Start 1
2
3 
python say 5!
4
5
6
My result is :  5
7

Output I really have:

Start 1
2
3

And here I do not really understand why it doesn't work on this line : "PyObject* my_function = PyObject_GetAttrString(my_module,"speak"); "

Thank you for reading this far, and much more if you're answering me!


Solution

  • The problem was that my python code was wrong : i didn't put the () to my print lines... So basic but we have to be carfull about our python code, the error may come from there !

    I used PyErr_Print(); , this allows us to get a specific output about errors and exceptions you can get from your python code ! (more informations there : https://docs.python.org/3/c-api/exceptions.html )

    A great thanks to Wim Lavrijsen for helping me to clarify my problem !

    Here is the rigth code that work now :

    C++ Code (main.cpp):

    #include <iostream>
    #include "C:/Users/Martin/AppData/Local/Programs/Python/Python37-32/include/Python.h"
    
    using namespace std;
    
    int main ()
    {
        cout << "Start 1 \n";
    
        Py_Initialize();
        cout << "2\n";  PyObject* my_module = PyImport_ImportModule("mat");
        cerr << my_module << "\n";
        PyErr_Print();
        cout << "3\n";  PyObject* my_function = PyObject_GetAttrString(my_module,"getfive");
        cout << "4\n";  PyObject* my_result = PyObject_CallObject(my_function,NULL);
        cout << "5\n";  int result = _PyLong_AsInt(my_result);
        cout << "6\n";  printf("My result is :  %d", result);
        cout << "\n7\n";
        Py_Finalize();
        return 0;
    }
    

    Python Code (mat.py):

    def getfive():
        print("python say 5 !")
        return 5
    
    def speak():
        print(speak)
    

    The errors i got :

    SyntaxError: Missing parentheses in call to 'print'. Did you mean print("python say 5 !")?
    SyntaxError: Missing parentheses in call to 'print'. Did you mean print("speak")?
    

    And the output i wanted

    Start 1 
    2
    0x790600
    3
    4
    python say 5 !
    5
    6
    My result is :  5
    7
    

    CONCLUSION : When you work with te Python/C API, use PyErr_Print() to check the Python code !