如何在Python脚本中通过cppyy实现C++参数的引用传递?
问题:cppyy调用接收结构体指针的C++函数时类型转换失败
在为现有C++库开发Python前端时,使用Python 3.10和cppyy 2.4.2,调用接收Parser_Conf*类型参数的print_conf_fromPtr函数时,出现类型转换错误。错误原因是通过cppyy.ll.addressof获取的是裸整数地址,无法被cppyy识别为Parser_Conf*类型指针。
相关代码片段
C++头文件(pconf.h)
struct Parser_Conf { std::string filename = ""; uint32_t dump_addr_st = 0; uint32_t dump_addr_end = 255; bool debug_session = false; bool use_xterm = true; }; void print_conf(Parser_Conf); void print_conf_fromPtr(Parser_Conf*);
Python代码(simple.py)核心问题部分
extract = boost.any_cast[cppyy.gbl.Parser_Conf](parserConfCapsule) # ... addr_of_extract = cppyy.ll.addressof(extract) cppyy.gbl.print_conf_fromPtr(addr_of_extract) # 此处报错
错误信息
TypeError: void ::print_conf_fromPtr(Parser_Conf*) => TypeError: could not convert argument 1
解决方案
1. 获取结构体的引用而非拷贝
boost.any_cast[cppyy.gbl.Parser_Conf]返回的是结构体的拷贝,后续操作的是临时对象,且cppyy.ll.addressof返回的是无类型的整数地址。改为获取引用:
# 用引用类型进行any_cast,避免拷贝 extract = boost.any_cast[cppyy.gbl.Parser_Conf&](parserConfCapsule)
2. 获取带类型的指针对象
使用cppyy.addressof(而非cppyy.ll.addressof)获取cppyy可识别的类型化指针,该函数返回的是对应C++类型的指针对象,可直接传入函数:
# 获取类型化的指针 conf_ptr = cppyy.addressof(extract) # 调用指针参数的函数 cppyy.gbl.print_conf_fromPtr(conf_ptr)
3. 简化的替代写法(直接传对象)
cppyy支持自动将对象转换为非const指针(如果函数参数是T*而非const T*),可以直接传入extract对象,cppyy会自动处理指针转换:
cppyy.gbl.print_conf_fromPtr(extract)
修正后的完整核心代码
parserConfCapsule = boost.any(cppyy.gbl.Parser_Conf()) assert parserConfCapsule.type() == cppyy.typeid(cppyy.gbl.Parser_Conf), "类型不匹配" # 获取结构体引用 extract = boost.any_cast[cppyy.gbl.Parser_Conf&](parserConfCapsule) extract.debug_session = False extract.filename = program_file_name # 调用传值函数 cppyy.gbl.print_conf(extract) # 调用指针参数函数(两种方式任选其一) # 方式1:显式获取指针 conf_ptr = cppyy.addressof(extract) cppyy.gbl.print_conf_fromPtr(conf_ptr) # 方式2:直接传对象,cppyy自动转指针 # cppyy.gbl.print_conf_fromPtr(extract)
关键说明
cppyy.ll.addressof返回的是底层内存地址的整数表示,没有类型信息,无法直接转换为C++指针类型;cppyy.addressof返回的是带类型的指针对象,符合cppyy的类型系统要求。- 使用
boost.any_cast时添加&获取引用,避免拷贝临时对象,确保修改的是boost.any中存储的原对象,同时指针指向的是有效内存。
内容的提问来源于stack exchange,提问作者Lorenzo
相关产品推荐
相关产品推荐

