8

In the following document about python embedding, it is well described how to embed python methods in "C" code. https://docs.python.org/3/extending/embedding.html

I tested the above code, it works well with the GCC g++ compiler as well.

But the above shows examples of calling the global methods not the class methods.

Could anyone show an example about how to create a Python object and call its method from C++?

1 Answer 1

12

By doing some investigation, I found that this can be done using the following fourAPIs in series.

  • PyModule_GetDict ; Gets items belonging to the python module. *

  • PyDict_GetItemString ; Gets the item corresponding to Python class name.

  • PyObject_CallObject; Creates the Python object. *
  • PyObject_CallMethod; Class a method of the object.

The following is the sample code that I created even though it still needs to be improved.

// Refer to the following website for more information about embedding the
// Python code in C++.
// https://docs.python.org/2/extending/embedding.html
int main() {
  PyObject *module_name, *module, *dict, *python_class, *object;

  // Initializes the Python interpreter
  Py_Initialize();

  module_name = PyString_FromString(
      "work.embedding_python_in_cpp.example.adder");

  // Load the module object
  module = PyImport_Import(module_name);
  if (module == nullptr) {
    PyErr_Print();
    std::cerr << "Fails to import the module.\n";
    return 1;
  }
  Py_DECREF(module_name);

  // dict is a borrowed reference.
  dict = PyModule_GetDict(module);
  if (dict == nullptr) {
    PyErr_Print();
    std::cerr << "Fails to get the dictionary.\n";
    return 1;
  }
  Py_DECREF(module);

  // Builds the name of a callable class
  python_class = PyDict_GetItemString(dict, "Adder");
  if (python_class == nullptr) {
    PyErr_Print();
    std::cerr << "Fails to get the Python class.\n";
    return 1;
  }
  Py_DECREF(dict);

  // Creates an instance of the class
  if (PyCallable_Check(python_class)) {
    object = PyObject_CallObject(python_class, nullptr);
    Py_DECREF(python_class);
  } else {
    std::cout << "Cannot instantiate the Python class" << std::endl;
    Py_DECREF(python_class);
    return 1;
  }

  int sum = 0;
  int x;

  for (size_t i = 0; i < 5; i++) {
    x = rand() % 100;
    sum += x;
    PyObject *value = PyObject_CallMethod(object, "add", "(i)", x); 
    if (value)
      Py_DECREF(value);
    else
      PyErr_Print();
  }
  PyObject_CallMethod(object, "printSum", nullptr);
  std::cout << "the sum via C++ is " << sum << std::endl;

  std::getchar();
  Py_Finalize();

  return (0);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Really appreciate this code. Would've been nice if you had included the python code as well to give a better idea.
Kindly add the Python Code file as well .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.