使用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++声明:

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<std::string*>(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一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值