0

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!

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • Since the code is in principle correct (modulo ref-counting) and since it fails after printing '3', my best guess is that `mat.py` is not found and `my_module` ends up being NULL, hence crashing the call between `3` and `4`. Can you add a `cerr << my_module << "\n";` to verify? – Wim Lavrijsen Nov 03 '19 at 21:47
  • @WimLavrijsen thank you for answering ! So i've done what you told me to do, so when i put `cerr << my_module << "\n";` it returns `0`. I guess it means that `my_module` is `NULL` as you say but i do not understand at all why is it null because mat.py and main.cpp are in the same folder ! Or maybe i need to add some spefcific code to make the system understandinf that mat.py is actually accessible ? – Martin Beaussart Nov 04 '19 at 08:31
  • Using the python interpreter directly or through the C-API have the same rules for importing, so try `import mat` from python first, as that may show a better error message (you can also call `PyErr_Print()` in your code.) As for location, it would work if the module and the compiled executable are in the same directory; location of main.cpp does not matter. You can set the PYTHONPATH environment variable to point to the directory where mat.py resides otherwise. – Wim Lavrijsen Nov 04 '19 at 15:30
  • @WimLavrijsen OMG THANK YOU MY FRIEND MY PROBLEM IS SOLVED ! Thanks to `PyErr_Print();` i got a better output answer from the Python compilator saying in short that i've forgotten the `()` to `print` lines from my python module ... I'm such an idiot urgh haha But thank you, i'm happy now i can use my python scipts code on C++ scipts now, and it's an amazing thing ! – Martin Beaussart Nov 05 '19 at 19:15

1 Answers1

0

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 !