前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt使用C/C++扩展Python内置模块

Qt使用C/C++扩展Python内置模块

作者头像
用户5908113
发布2019-08-23 15:52:13
1K0
发布2019-08-23 15:52:13
举报
文章被收录于专栏:Pou光明Pou光明

之前和大家介绍过在C/C++中嵌入Python,本次和大家分享下使用C/C++扩展Python内置模块的方法。

被扩展出来的新模块可以做两件无法直接在Python中完成的事情:一可以实现新的内置对象类型,二则可以调用C库函数和一些其他的系统调用。

使用平台:ubuntu14.04、python3.5、Qt 5.5.1

下面借助Qt创建一个叫libpy3extend 的Python内置模块,它可以做一个简单的加法操作,还可以返回一个自定义的数据类型。调用形式如下:

import libpy3extend

libpy3extend.extend_add(1,99)

ibpy3extend.extend_str()

先使用Qt建一个生成库的工程,之后按照步骤进行操作即可。

1. extend.cpp文件首先是包含所用到的头文件:

#include <iostream>

#include <python3.5/Python.h>

2. 向extend.cpp模块文件中添加C函数,该函数在执行libpy3extend.extend_add(1,99) 时被调用。C函数总是有两个参数,通常命名为self和args。

代码语言:javascript
复制
static PyObject *extend_add(PyObject *self, PyObject *args)
{
    (void)(self);
    PyObject *pArgs = NULL;

    int result = 0;
    int arg1 = 0;
    int arg2 = 0;

    if (!PyArg_ParseTuple(args, "ii",&arg1,&arg2))
    {
        std::cerr << "parameters error" << std::endl;
        Py_INCREF(Py_None);
        pArgs = Py_None;
    }
    else
    {
        result = arg1 + arg2;
        pArgs = Py_BuildValue("i", result);
    }

    return pArgs;
}

args参数是一个元组对象,使用PyArg_ParseTuple()函数来解析,解析规则可参考python文档

https://docs.python.org/3/c-api/arg.html#arg-parsing

3. 创建模块方法表并在表中列出函数名称和地址。

代码语言:javascript
复制
static PyMethodDef extendMethods[] = {
    //extend add
    {"extend_add", extend_add, METH_VARARGS, NULL},
    {"extend_str", extend_str, METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}
};

METH_VARARGS表示该函数希望参数传递为元组数据以使用PyArg_ParseTuple()函数来解析。

4. 在模块定义结构中引用方法表

代码语言:javascript
复制
static struct PyModuleDef extendMoudle =
    {
        PyModuleDef_HEAD_INIT,
        "py3extend",          /* name of module */
        NULL,                 /* module documentation, may be NULL */
        -1,                   /* size of per-interpreter state of the module,
                                 or -1 if the module keeps state in global                     variables. */
        extendMethods,

        NULL,
        NULL,
        NULL,
        NULL
    };

5. 将刚才定义的结构传递给模块初始化函数中的解释器。

注意:必须命名初始化函数PyInit_name(),其中name是模块的名称。我这里模块 名称是py3extend,但是由于生成的是库文件,会自动加上lib前缀,所以这 里模块名称是libpy3extend,不是该名称会报

ImportError: dynamic module does not define module export function (PyInit_libpy3extend)

这个错误。

代码语言:javascript
复制
PyMODINIT_FUNC PyInit_libpy3extend(void)
{
    //to use thread in extend moudle
//    if (!PyEval_ThreadsInitialized()) {
//      PyEval_InitThreads();
//    }

    return PyModule_Create(&extendMoudle);
}

到这里就可以借助Qt生成库文件了,如果不知道怎么使用Qt生成库文件可以参考Qt创建共享库该文章。

接下来是如何使用库文件。将库文件与python测试文件放到同一目录下,即可运行测试。如图:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Pou光明 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档