• 使用sipParseArgs/sipBuildResult进行python/C++对象的转换


    SIP库是用于python/C++对象互相转换的桥梁,由于python本身运行速度非常慢,所以很多第三方模块在底层会使用C++来编写,并提供python接口供python调用,在提供对象转换时,sipParseArgs和sipBuildResult是一对经常使用的函数,其中sipParseArgs用于将python对象转换成C++对象,而sipBuildResult则用于将C++对象转换成python对象,即PyObject,由于网络上关于它们的资料非常少,因此有必要在此记录一下,如果发现有任何错误,请在评论区留言告知。

    本文使用python3.8,SIP版本为6.0.3

    sipParseArgs

    其原型为int sipParseArgs(PyObject* sipParseErr, PyObject* obj, const char* format ...),

    返回值为非0时代表成功,为0时代表失败,obj代表需要解析的python对象,format代表解析规则(区分大小写),根据规则不同,format后面跟着的参数也不相同,具体如下:

    预定义参数意义:sipSelf:即python中的self。sipTypeDef:类型定义,即形如sipType_MyType的类型定义,代表一个完整的C++类。sipCpp:指向原始的C++对象的指针。sipRes:代表C++返回值。

    注意,你可以在format字符串中使用 () 来代表tuple, [] 来代表list, {}来代表dict, 例如 (id) 表示一个两个元素的tuple,第一个元素为int型,第二个元素为double型

    格式类型参数描述
    =size_tsize_t* out1提取size_t
    1P0Python objectPyObject** out1提取PyObject(猜测跳过parse过程直接返回了)
    aecharchar* out1从大小为1的bytes/string对象中提取char,e表示encoding方式,为A时代表ASCII,为L时代表Latin-1,为8时代表UTF-8
    bboolbool* out1提取bool
    ccharchar* out1从大小为1的bytes对象中提取char
    ddoubledouble* out1提取double
    ffloatfloat* out1提取float
    g字符串const char**, SIP_SSIZE_T* size从bytes对象中提取字符串,如果对象为None则返回nullptr和0
    hshortshort* out1提取short
    iintint* out1提取int
    llonglong* out1提取long
    munsigned longunsigned long* out1提取unsigned long
    nlong longlong long* out1提取long long
    ounsigned long longunsigned long long* out1提取unsigned long long
    sconst char*const char** out1提取const char*
    tunsigned shortunsigned short* out1提取unsigned short
    uunsigned intunsigned int* out1提取unsigned int
    vvoidvoid* out1提取void
    wwchar_twchar_t* out1从大小为1的string对象中提取wchar_t
    xwchar_t*字符串wchar_t** out1从string对象中提取\0结尾的宽字符串,如果对象为None则返回nullptr
    Aechar*字符串int out1, const char** out2从bytes/string对象中提取\0结尾的字符串,e代表encoding方式,为A时代表ASCII,为L时代表Latin-1,为8时代表UTF-8,如果对象为None则返回nullptr
    B联合类型PyObject** sipSelf, sipTypeDef typeDef, PyObject** sipCppsipSelf,sipCpp为输出参数,typeDef为输入参数
    E联合类型sipTypeDef typeDef, Enum* out1提取枚举类型值
    J0联合类型sipTypeDef typeDef, const T* out1, int* out1State 提取class类型值,out1State指示提取状态,out1可能存在默认值例如nullptr,使用完毕后应当使用sipReleaseType(T* out1, sipTypeDef typeDef, int out1State)释放out1对象
    J1联合类型sipTypeDef typeDef, const T* out1, int* out1State 提取class类型值,out1State指示提取状态,out1使用完毕后应当使用sipReleaseType(T* out1, sipTypeDef typeDef, int out1State)释放out1对象
    J8联合类型sipTypeDef typeDef, T* out1提取class类型值,out1可能存在默认值例如nullptr,无需释放out1对象
    J9联合类型sipTypeDef typeDef, T* out1提取class类型值,无需释放out1对象
    Lsigned charsigned char* out1提取signed char
    Munsigned charunsigned char* out1提取unsigned char
    Vvoidptrvoid**提取void*
    |----跟在该符号后面的是可选参数。可选参数即在C++头文件的函数声明中带有默认值的参数

    例子:编写一个python接口函数:

    假设有以下C++声明:

    1. class MyClass
    2. {
    3. public:
    4. int setInfo(const std::string& name, int value = -1);
    5. };

    现在为MyClass类的成员函数setInfo创建python接口 :

    1. static PyObject* invoke_MyClass_setInfo(PyObject* sipSelf, PyObject* sipArgs)
    2. {
    3. PyObject* sipParseErr = SIP_NULLPTR;
    4. const std::string* a0;
    5. int a0State = 0;
    6. int a1 = -1;
    7. MyClass* sipCpp;
    8. if (sipParseArgs(&sipParseErr, sipArgs, "BJ1|i", &sipSelf, sipType_MyClass, &sipCpp, sipType_std_string, &a0, &a0State, &a1))
    9. {
    10. int sipRes = sipCpp->setInfo(*a0, a1);
    11. sipReleaseType(const_cast(a0), sipType_std_string, a0State);
    12. return sipBuildResult(nullptr, "i", &sipRes); // or use PyLong_FromLong(sipRes) directly
    13. }
    14. return SIP_NULLPTR;
    15. }

    sipBuildResult

    其原型为PyObject* sipBuildResult(int* isErr, const char* format ...)

    format意义与sipParseArgs一致

  • 相关阅读:
    Blazor前后端框架Known-V1.2.16
    .NET Framework 4.5.2组件安装 官网免费版
    .NET 6 实现滑动验证码(十)、大结局:前端代码实战,vue3与HTML+JQuery
    云轴科技ZStack与华东师范大学共建产教融合基地
    前端实现给文字添加动态背景
    picoctf_2018_shellcode
    Hadoop生态之Yarn
    2022年12月STEMAC++中级组编程题
    4.8烧饼排序问题
    Hexagon_V65_Programmers_Reference_Manual(5)
  • 原文地址:https://blog.csdn.net/yuchno1/article/details/126498691