# 常用API ## 1、运行Python指令 ```python PyRun_SimpleString("print(os.getcwd(),a)"); pyext.eval(R"(a+='qwer')"); ``` ## 2、加载Python模块 ```python PyObject * pModule =PyImport_ImportModule("tp"); # test:Python文件名,若脚本有错则返回空 PyRun_SimpleString("import os"); ``` ## 3、给Python的变量赋值 对于数值,使用Py_BuildValue: ```python 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} ``` 对于其他数据结构,使用相应的函数设置,例如: ```python PyObject *pArgs = PyTuple_New(1); PyObject *pDict = PyDict_New(); # 创建字典类型变量 PyDict_SetItemString(pDict, "Name", Py_BuildValue("s", "YQC")); # 往字典类型变量中填充数据 PyDict_SetItemString(pDict, "Age", Py_BuildValue("i", 25)); # 往字典类型变量中填充数据 PyTuple_SetItem(pArgs, 0, pDict);# 0---序号 将字典类型变量添加到参数元组中 ``` 构造好对象以后,通过PyObject_SetAttrString来设置进入Python中: ```python PyObject *ps=PyUnicode_DecodeUTF8(val,strlen(val),"ignore"); # 构造了一个对象 PyObject_SetAttrString(p_main_Module,key,ps); # 设置 ``` ## 4、获取Python变量的值 首先取得变量的指针,然后通过PyArg_Parse解析 ```python pModule =PyImport_ImportModule("__main__"); pReturn = PyObject_GetAttrString(pModule, "a"); # 可以获得全局变量 int size = PyDict_Size(pReturn); PyObject *pNewAge = PyDict_GetItemString(pReturn, "Age"); int newAge; PyArg_Parse(pNewAge, "i", &newAge); ``` 对于元组的解析: ```python 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、调用Python函数 ```python PyObject * pfun=PyObject_GetAttrString(pModule, "testdict"); # testdict:Python文件中的函数名 PyObject *pReturn = PyEval_CallObject(pfun, pArgs); # 调用函数 ``` ## 6、设置函数让Python调用 首先定义c函数,然后声明方法列表,然后声明模块,然后增加这个模块,最后调用 ```python static int numargs = 1890; static PyObject* emb_numargs(PyObject *self, PyObject *args) # C函数 { if(!PyArg_ParseTuple(args, ":numargs")) return NULL; return PyLong_FromLong(numargs); } static PyMethodDef EmbMethods[] = { # 方法列表 { "numargs", emb_numargs, METH_VARARGS, "Return the number of arguments received by the process." }, { NULL, NULL, 0, NULL } }; static PyModuleDef EmbModule = { # 模块声明 PyModuleDef_HEAD_INIT, "emb", NULL, -1, EmbMethods, NULL, NULL, NULL, NULL }; static PyObject* PyInit_emb(void) # 模块初始化函数 { return PyModule_Create(&EmbModule); } # 增加模块: PyImport_AppendInittab("emb", &PyInit_emb); # 增加一个模块 ``` ## 参考链接 + https://docs.python.org/zh-cn/3.8/c-api/index.html