C++ call Python basic function example details

  • 2020-05-17 06:03:26
  • OfStack

c++ call Python first installs Python, taking win7 as an example, Python path is: c:\Python35\, and c++ code is compiled by mingw.

To write the makefile file, first add the include path:

inc_path += c:/Python35/include

Then add the link parameter:

ld_flag += c:/Python35/libs/libpython35.a

Add a header file reference to the source file:

#include "Python.h"

The Python interpreter needs to be initialized and terminated after completing the task:


void start()
{
  int r=Py_IsInitialized(); //1 Is already initialized 
  if (r==0)
  {
    //Py_SetPythonHome(L"C:\\Python35");
    Py_Initialize(); // Initialize the 
    p_main_Module =PyImport_ImportModule("__main__");
    if (!p_main_Module)
    {
      throw "";
    }
  }
}
void end()
{
  Py_Finalize(); // Clean up the 
}

When the program is deployed, the c:\Python35\lib directory can be copied to the path of the executing program, or by Py_SetPythonHome(L"C:\\Python35"); Set up the installation directory for Python.

Basic requirements for C++ to invoke Python:

1. Run the Python command


PyRun_SimpleString("print(os.getcwd(),a)");
pyext.eval(R"(a+='qwer')");

2. Load Python module


PyObject * pModule =PyImport_ImportModule("tp"); //test:Python The file name , Returns nothing if the script is wrong 
PyRun_SimpleString("import os");

3. Assign a value to the variable Python

For values, Py_BuildValue is used:


Py_BuildValue("") None
Py_BuildValue("i", 123) 123
Py_BuildValue("iii", 123, 456, 789) (123, 456, 789)
Py_BuildValue("s", "hello") 'hello'
Py_BuildValue("ss", "hello", "world") ('hello', 'world')
Py_BuildValue("s#", "hello", 4) 'hell'
Py_BuildValue("()") ()
Py_BuildValue("(i)", 123) (123,)  
Py_BuildValue("(ii)", 123, 456) (123, 456)
Py_BuildValue("(i,i)", 123, 456) (123, 456)
Py_BuildValue("[i,i]", 123, 456) [123, 456]
Py_BuildValue("{s:i,s:i}", "abc", 123, "def", 456) {'abc': 123, 'def': 456}

For other data structures, use the appropriate function Settings, such as:


PyObject *pArgs = PyTuple_New(1);
PyObject *pDict = PyDict_New();  // Create a dictionary type variable  
PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "WangYao")); // Populate the dictionary type variable with data  
PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25)); // Populate the dictionary type variable with data  
PyTuple_SetItem(pArgs, 0, pDict);//0--- The serial number   Adds a dictionary type variable to the parameter tuple  

After the object is constructed, PyObject_SetAttrString is set to enter Python:


PyObject *ps=PyUnicode_DecodeUTF8(val,strlen(val),"ignore"); // constructed 1 An object 
PyObject_SetAttrString(p_main_Module,key,ps); // Set up the 

4. Get the value of the Python variable

First get the pointer to the variable and then parse through PyArg_Parse


pModule =PyImport_ImportModule("__main__");
pReturn = PyObject_GetAttrString(pModule, "a"); // You can get global variables 
int size = PyDict_Size(pReturn); 
PyObject *pNewAge = PyDict_GetItemString(pReturn, "Age"); 
int newAge;
PyArg_Parse(pNewAge, "i", &newAge); 

Analysis of tuples:


int ok;
ok = PyArg_ParseTuple(args, "s", &s); //Python call: f('whoops!')
ok = PyArg_ParseTuple(args, "lls", &k, &l, &s);//Python call: f(1, 2,'three')
ok = PyArg_ParseTuple(args, "(ii)s#", &i, &j, &s, &size);//Python call: f((1, 2), 'three')
ok = PyArg_ParseTuple(args, "s|si", &file, &mode, &bufsize);//Python calls:
//f('spam')
//f('spam', 'w')
//f('spam', 'wb', 100000)

5. Call Python function


PyObject * pfun=PyObject_GetAttrString(pModule, "testdict"); //testdict:Python The function name in the file 
PyObject *pReturn = PyEval_CallObject(pfun, pArgs); // Call a function 

6. Set the function to be called by Python

First define the c function, then declare the list of methods, then declare the module, then add the module, and finally call it


static int numargs=1890;
static PyObject* emb_numargs(PyObject *self, PyObject *args) //C function 
{
  if(!PyArg_ParseTuple(args, ":numargs"))
    return NULL;
  return PyLong_FromLong(numargs);
}
static PyMethodDef EmbMethods[] = { // Methods list 
  {"numargs", emb_numargs, METH_VARARGS,
   "Return the number of arguments received by the process."},
  {NULL, NULL, 0, NULL}
};
static PyModuleDef EmbModule = { // Module declaration 
  PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods,
  NULL, NULL, NULL, NULL
};
static PyObject* PyInit_emb(void) // Module initialization function 
{
  return PyModule_Create(&EmbModule);
}
// Add modules: 
PyImport_AppendInittab("emb", &PyInit_emb); // increase 1 A module 

Part of Python code:


PyRun_SimpleString("print(os.getcwd(),a)");
pyext.eval(R"(a+='qwer')");
0

Related articles: