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