2024-06-17 17:44:52 发布
网友
我希望能够从Python将数值数据的缓冲区(即实现缓冲区协议的东西,比如numpy数组)传递到c++中:
>>> import mymod >>> import numpy >>> mymod.some_func(numpy.array([1,2,3]))
用c++以某种方式接收:
印刷品
1 2 3
我真的不在乎[something]是什么(指针、std::vector等等)。有人知道怎么做吗?令人惊讶的是关于它的信息很少。。。在
好的<get_ready_for_this.mp3>这是我解决这个问题的方法。在
<get_ready_for_this.mp3>
首先,我创建了一个表示我想要的缓冲区的类型,以及一些helpers函数来将数据缓冲区转换为目标格式。您可以很容易地修改它以使其更灵活,但我只需要一个复杂的浮点值数组。在
// vector of complex values typedef vector<cfloat> cbuffer; // helper to copy data template<typename T> void cbuffer_copy_from(cbuffer& cbuf, void *ptr, ssize_t len, ssize_t stride) { cbuf.reserve(len); // convert elements into buffer char* cptr = (char*)ptr; for (ssize_t ii=0; ii < len; ii++) { cbuf.emplace_back(*reinterpret_cast<T*>(cptr)); cptr += stride; } }; // populate vector from source template<typename T> void cbuffer_from(cbuffer& cbuf, void *ptr, ssize_t len, ssize_t stride) { cbuffer_copy_from<T>(cbuf, ptr, len, stride); } // fast path for data that's already cfloat template <> void cbuffer_from<cfloat>(cbuffer& cbuf, void *ptr, ssize_t len, ssize_t stride) { // if stride is right, we can just copy the data if (stride == sizeof(cfloat)) { cbuf.resize(len); memcpy(&cbuf[0], ptr, len*sizeof(cfloat)); } else { cbuffer_copy_from<cfloat>(cbuf, ptr, len, stride); } }
然后,我构建了一个从python到cbuffer类型的自定义转换器:
convertible()函数检查Python对象是否实现了缓冲区协议。然后construct()函数实际上从对象中提取一个缓冲区,并通过上面的helper函数将其转换为所需的格式。如果我们在任何一步失败,清理并抛出一个运行时异常。在
convertible()
construct()
最后,我们在模块中实例化转换器:
// define python module BOOST_PYTHON_MODULE(module) { // register python -> c++ converters python_to_cbuffer(); def("test", test); }
如果我们创建一个测试函数:
void test(cbuffer buf) { for (cfloat val : buf) { printf("(%f, %f)\n", val.re, val.im); } }
然后在python中:
>>> module.test(numpy.array([1+2j,3+4j],dtype=numpy.complex64)) (1.000000, 2.000000) (3.000000, 4.000000) >>> module.test(numpy.array([1,2],'b')) (1.000000, 0.000000) (2.000000, 0.000000) >>> module.test(numpy.array([1,2],'i')) (1.000000, 0.000000) (2.000000, 0.000000) >>> module.test(numpy.array([1,2],'l')) (1.000000, 0.000000) (2.000000, 0.000000)
享受吧!在
好的
<get_ready_for_this.mp3>
这是我解决这个问题的方法。在首先,我创建了一个表示我想要的缓冲区的类型,以及一些helpers函数来将数据缓冲区转换为目标格式。您可以很容易地修改它以使其更灵活,但我只需要一个复杂的浮点值数组。在
然后,我构建了一个从python到cbuffer类型的自定义转换器:
^{pr2}$convertible()
函数检查Python对象是否实现了缓冲区协议。然后construct()
函数实际上从对象中提取一个缓冲区,并通过上面的helper函数将其转换为所需的格式。如果我们在任何一步失败,清理并抛出一个运行时异常。在最后,我们在模块中实例化转换器:
如果我们创建一个测试函数:
然后在python中:
享受吧!在
相关问题 更多 >
编程相关推荐