Cython如何遵循C++模板规则正确包装C++模板函数
Cython包装C++模板复数数组转换函数的实现方法
原代码与问题说明
待包装的C++函数是一个双模板参数的CSI数组类型转换工具,实现不同基础类型的复数向量转换:
/** * A CSI data format converter * @tparam OutputValueType * @tparam InputValueType * @param inputArray * @return */ template<typename OutputValueType, typename InputValueType> static std::vector<std::complex<OutputValueType>> convertCSIArrayType(const std::vector<std::complex<InputValueType>> &inputArray) { std::vector<std::complex<OutputValueType>> outputArray(inputArray.size()); for (auto i = 0; i < inputArray.size(); i++) { outputArray[i] = std::complex<OutputValueType>(inputArray[i].real(), inputArray[i].imag()); } return outputArray; }
最初的包装写法存在两处核心错误:
- 未按照Cython语法声明模板参数列表,直接在函数签名中使用
OutputValueType/InputValueType占位符会被识别为未定义类型 - 原函数是全局静态函数,不属于
CSISegment类的成员,放入cdef cppclass块中不符合原代码的链接属性
初始错误写法如下:
cdef cppclass CSISegment: std::vector<std::complex<OutputValueType>> convertCSIArrayType(const std::vector<std::complex<InputValueType>> &inputArray)
正确包装实现
首先需要在.pxd声明文件或.pyx文件头部引入依赖的C++标准库类型绑定:
from libcpp.vector cimport vector from libcpp.complex cimport complex
场景1:包装全局静态模板函数(匹配当前C++代码定义)
直接在全局作用域声明模板函数,Cython中模板参数放在函数名后的方括号内:
cdef vector[complex[OutputValueType]] convertCSIArrayType[InputValueType, OutputValueType]( const vector[complex[InputValueType]] &inputArray )
场景2:如果后续将该函数改为CSISegment类的成员模板函数
在cppclass块内声明时,同样需要显式标注模板参数列表:
cdef cppclass CSISegment: cdef vector[complex[OutputValueType]] convertCSIArrayType[InputValueType, OutputValueType]( const vector[complex[InputValueType]] &inputArray )
调用规则
Cython不支持C++的模板参数隐式推导,调用时必须显式传入模板实参,示例:
# 示例:将float类型复数向量转换为double类型复数向量 cdef vector[complex[float]] input_csi # 此处省略input_csi的赋值逻辑 cdef vector[complex[double]] output_csi = convertCSIArrayType[float, double](input_csi)
注意:所有需要用到的模板类型组合都必须显式指定,未显式实例化的类型组合会在C++编译阶段报链接错误。
内容的提问来源于stack exchange,提问作者HerrTian
相关产品推荐
相关产品推荐

