使用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_t size_t* out1 提取size_t
1P0 Python object PyObject** out1 提取PyObject(猜测跳过parse过程直接返回了)
ae char char* out1 从大小为1的bytes/string对象中提取char,e表示encoding方式,为A时代表ASCII,为L时代表Latin-1,为8时代表UTF-8
b bool bool* out1 提取bool
c char char* out1 从大小为1的bytes对象中提取char
d double double* out1 提取double
f float float* out1 提取float
g 字符串 const char**, SIP_SSIZE_T* size 从bytes对象中提取字符串,如果对象为None则返回nullptr和0
h short short* out1 提取short
i int int* out1 提取int
l long long* out1 提取long
m unsigned long unsigned long* out1 提取unsigned long
n long long long long* out1 提取long long
o unsigned long long unsigned long long* out1 提取unsigned long long
s const char* const char** out1 提取const char*
t unsigned short unsigned short* out1 提取unsigned short
u unsigned int unsigned int* out1 提取unsigned int
v void void* out1 提取void
w wchar_t wchar_t* out1 从大小为1的string对象中提取wchar_t
x wchar_t*字符串 wchar_t** out1 从string对象中提取\0结尾的宽字符串,如果对象为None则返回nullptr
Ae char*字符串 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** sipCpp sipSelf,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对象
L signed char signed char* out1 提取signed char
M unsigned char unsigned char* out1 提取unsigned char
V voidptr void** 提取void*
| -- -- 跟在该符号后面的是可选参数。可选参数即在C++头文件的函数声明中带有默认值的参数

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

假设有以下C++声明:

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

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

static PyObject* invoke_MyClass_setInfo(PyObject* sipSelf, PyObject* sipArgs)
{
    PyObject* sipParseErr = SIP_NULLPTR;
    const std::string* a0;
    int a0State = 0;
    int a1 = -1;
    MyClass* sipCpp;
    if (sipParseArgs(&sipParseErr, sipArgs, "BJ1|i", &sipSelf, sipType_MyClass, &sipCpp, sipType_std_string, &a0, &a0State, &a1))
    {
        int sipRes = sipCpp->setInfo(*a0, a1);
        sipReleaseType(const_cast(a0), sipType_std_string, a0State);
        return sipBuildResult(nullptr, "i", &sipRes);  // or use PyLong_FromLong(sipRes) directly
    }
    return SIP_NULLPTR;
}

sipBuildResult

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

format意义与sipParseArgs一致

你可能感兴趣的:(c++,开发语言,python)