栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

C调用python类的正确方法

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C调用python类的正确方法

 

C或C++调用python一般都可以使用python自带的库完成,首先添加python.h的头文件,链接时加上对应的库即可。

但是在C/C++程序中使用到python的类时会遇到很多坑,网上搜会得到很多相似的方法如下所示

首先声明,以下的方法是有问题的,有问题的地方我会使用红字标出

注: 下述所有导入方法在导入失败时不会报错, 只会返回空指针.

第一步是导入.py文件:

  1. 使用PyObject* pModule来存储导入的.py文件模块, 调用的方法是PyImport_ImportModule(path):  PyObject* pModule = PyImport_ImportModule("testpy"); 
  2. 使用PyObject* pDict来存储导入模块中的方法字典, 调用的方法是PyModule_GetDict(module):  PyObject* pDict = PyModule_GetDict(pModule); 

这样就完成了.py文件的导入.

第二步是导入已导入模块中的方法或类:

  1. 获取方法, 调用的方法是PyDict_GetItemString(dict, methodName): PyObject* pFunHi = PyDict_GetItemString(pDict, "sayhi"); 
  2. 获取类, 调用的方法同上, 注意红体部分的字符串对应于.py文件中的类/方法名:  PyObject* pClassSecond = PyDict_GetItemString(pDict,"Second"); 

第三步是使用导入的方法或类:

  1. 使用方法, 调用PyObject_CallFunction(pFunc, "s", args)即可:  PyObject_CallFunction(pFunHi, "s", "lhb"); 
  2. 使用类构造对象, 调用PyInstance_New(pClass, NULL, NULL)即可:  PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL); , 注意其中的pClassSecond为第二步.2中获取的类指针
  3. 使用类对象的方法, 调用PyObject_CallMethod(pInstance, methodname, "O", args)即可:  PyObject_CallMethod(pInstanceSecond,"invoke", "O", pInstancePerson); 
  4. 上述调用中的"s"和"O"代表的是参数列表的类型, 我们可以在 Py_BuildValue 找到所有的类型, 本文最后也附了此表.

PyInstance_New是python2使用的函数,python3则使用新的函数PyInstanceMethod_New,国内很多文章都认为这两个函数返回的是类的实例对象,其实不然,它们返回的是该类的构造函数对象。

按照上面文章的步骤做在不涉及修改类的成员变量时是没有问题的,如果有python类

class Test:
    def __init__(self):
        self.i = 1
        print("init!")

    def modify(self):
        self.i+=1

    def do(self):
        print(self.i)

如果使用上面的方法使用这个类,调用do方法是不会有问题的,可以成功打印,但是如果调用modify则会报错,PyErr_Print打印错误信息则会提示i不存在。

并且在PyInstance_New或PyInstanceMethod_New时并不会打印init!,说明构造函数根本没有被调用。

正确的调用方式则应该是

PyObject* pConstruct = PyInstanceMethod_New(pClass);
PyObject* pIns = PyObject_CallObject(pConstruct,nullptr);
PyObject_CallMethod(pIns,"modify", nullptr); 
PyObject_CallMethod(pIns,"do", nullptr); 

使用PyInstanceMethod_New获得构造函数后才能构造对象,并且调用时不需要传递自身。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/833592.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号