51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

C/C++ 编写 Python 扩展-传递参数(3)

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
赞(0)
未经允许不得转载:工具盒子 » C/C++ 编写 Python 扩展-传递参数(3)