https://docs.python.org/3.8/c-api/
导出函数:
#include <string> #include <iostream> #include <stdlib.h> #include "Python.h" #include "structmember.h" #define MODULE_NAME "mytest" // 位置参数: 接收整数和字符串 extern "C" PyObject* py_test_function1(PyObject *self, PyObject *args) { int a = 0; char *b = NULL; // 接受并将位置参数拷贝到指定的缓冲区中 // PyArg_ParseTuple 会为字符串开辟缓冲器,不需要自己开辟空间 PyArg_ParseTuple(args, "is", &a, &b); printf("a = %d, b = %s\n", a, b); Py_RETURN_NONE; } // 位置参数: 接收序列参数 extern "C" PyObject* py_test_function2(PyObject *self, PyObject *args) { PyObject *obj = NULL; void *b = NULL; // 接收传递来的参数 PyArg_ParseTuple(args, "O", &obj); // 获得元素长度 int len = PySequence_Size(obj); printf("sequece length: %d\n", len); // 将参数转换为序列 PyObject* seq = PySequence_Fast(obj, "expect a sequece"); // 遍历序列元素 for (int i=0; i<len; ++i) { // 从序列中取出元素 PyObject* item = PySequence_Fast_GET_ITEM(seq, i); // 转换数据类型 long v = PyLong_AsLong(item); printf("%ld\n", v); } Py_RETURN_NONE; } // 关键字参数 extern "C" PyObject* py_test_function3(PyObject *self, PyObject *args, PyObject *kwargs) { int a = NULL; int b = NULL; int c = NULL; int d = NULL; int e = NULL; static char* kwlist[] = {"a", "b", "c", "d", "e", NULL}; // 接下传入的位置参数 PyArg_ParseTupleAndKeywords(args, kwargs, "ii|iii", kwlist, &a, &b, &c, &d, &e); printf("%d\n", a); printf("%d\n", b); printf("%d\n", c); printf("%d\n", d); printf("%d\n", e); Py_RETURN_NONE; } // 定义导出模块信息 PyMODINIT_FUNC PyInit_mytest() { static PyMethodDef py_methods[] = { {"test_func1", py_test_function1, METH_VARARGS, "测试函数"}, {"test_func2", py_test_function2, METH_VARARGS, "测试函数"}, {"test_func3", (PyCFunction)py_test_function3, METH_VARARGS | METH_KEYWORDS, "测试函数"}, {NULL, NULL, 0, NULL} }; static PyModuleDef py_modules = { PyModuleDef_HEAD_INIT, MODULE_NAME, NULL, -1, py_methods }; return PyModule_Create(&py_modules); }
setup.py 文件:
#setup.py from distutils.core import setup, Extension # 模块名 MODULE_NAME = 'mytest' setup(name=MODULE_NAME, ext_modules=[ Extension( MODULE_NAME, sources=['libtest2.cpp'], extra_compile_args=['-Wall', '-g'], include_dirs=['/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8/'] )] )
Python 调用文件:
from mytest import * test_func1(10, "abc") print('-' * 30) test_func2((10, 20, 30)) print('-' * 30) test_func3(a=10, b=20, c=100, d=200, e=300)
程序运行结果:
a = 10, b = abc ------------------------------ sequece length: 3 10 20 30 ------------------------------ 10 20 100 200 300