使用Python、C+返回和传递原始POD指针(数组)+;,和pybind11 我有一个C++函数,它返回一个原始代码>浮点< /C>指针,另一个C++函数接受一个原始代码>浮点< /Cord>指针作为参数。比如: float* ptr = something; float* get_ptr(void) { return ptr; } void use_ptr(float* ptr) { do_work(ptr); }
我希望能够使用Python传递指针。大概是这样的:使用Python、C+返回和传递原始POD指针(数组)+;,和pybind11 我有一个C++函数,它返回一个原始代码>浮点< /C>指针,另一个C++函数接受一个原始代码>浮点< /Cord>指针作为参数。比如: float* ptr = something; float* get_ptr(void) { return ptr; } void use_ptr(float* ptr) { do_work(ptr); },python,c++,pybind11,Python,C++,Pybind11,我希望能够使用Python传递指针。大概是这样的: import my_native_functions as native ptr = native.get_ptr() native.use_ptr(ptr) 我正在使用pybind11创建我的本机python模块,但我不知道如何为get\u ptr()函数创建绑定。如果我只做以下几点: PYBIND11_MODULE(my_native_functions, m) { m.def("get_ptr", &get_ptr);
import my_native_functions as native
ptr = native.get_ptr()
native.use_ptr(ptr)
我正在使用pybind11创建我的本机python模块,但我不知道如何为get\u ptr()
函数创建绑定。如果我只做以下几点:
PYBIND11_MODULE(my_native_functions, m)
{
m.def("get_ptr", &get_ptr);
m.def("use_ptr", &use_ptr);
}
函数返回一个PythonFloat
对象。我想这是有意义的,因为python中没有指针类型。但是,由于这现在是一个简单的浮点
,当我调用use_ptr()
函数并在C/C++中迭代指针时,只有数组的第一个元素是正确的。其余的都是垃圾。要解决这个问题,在C++中,我必须把指针从<代码> STD::SiZeSt。通过这样做,一切都很好
但是,我想问:是否有一种“正确的方法”可以实现上述目标,而不必使用pybind11从std::size\t
如果你想知道我为什么这么做:
我明白我所做的不是类型安全的。此外,我从不在Python端接触指针/整数。我只是从一个本机模块中检索它并将其传递给另一个本机模块。此外,我不能将指针强制转换为某种numpy视图,因为指针并不总是在CPU上。有时我想传递CUDA指针。从CUDA指针创建py::array\u t
是不可能的,除非我复制数据(我不想这样做)
谢谢。如前所述,将原始指针包装在自定义的“智能”指针类中(仅假装真正智能)。您可以在此类中添加一些附加信息,例如数组元素的大小和元素的数量。这将使它成为C++侧的一个通用数组描述符(但不在Python端),因为您没有将Pothon的原始指针暴露出来。 对于一个更简单的选项,只需将指针包装在任何旧类中,以便对Python隐藏它。无需将其作为自定义智能指针公开给Python。这里有一个例子可以做到这一点:
#include <pybind11/pybind11.h>
#include <memory>
#include <iostream>
namespace py = pybind11;
template <class T> class ptr_wrapper
{
public:
ptr_wrapper() : ptr(nullptr) {}
ptr_wrapper(T* ptr) : ptr(ptr) {}
ptr_wrapper(const ptr_wrapper& other) : ptr(other.ptr) {}
T& operator* () const { return *ptr; }
T* operator->() const { return ptr; }
T* get() const { return ptr; }
void destroy() { delete ptr; }
T& operator[](std::size_t idx) const { return ptr[idx]; }
private:
T* ptr;
};
float array[3] = { 3.14, 2.18, -1 };
ptr_wrapper<float> get_ptr(void) { return array; }
void use_ptr(ptr_wrapper<float> ptr) {
for (int i = 0; i < 3; ++i)
std::cout << ptr[i] << " ";
std::cout << "\n";
}
PYBIND11_MODULE(Ptr,m)
{
py::class_<ptr_wrapper<float>>(m,"pfloat");
m.def("get_ptr", &get_ptr);
m.def("use_ptr", &use_ptr);
}
#包括
#包括
#包括
名称空间py=pybind11;
模板类ptr_包装器
{
公众:
ptr_包装器():ptr(nullptr){}
ptr_包装器(T*ptr):ptr(ptr){}
ptr_包装器(constptr_包装器&其他):ptr(other.ptr){}
T&运算符*()常量{return*ptr;}
T*运算符->()常量{return ptr;}
T*get()常量{return ptr;}
void destroy(){delete ptr;}
运算符[](std::size_T idx)常量{return ptr[idx];}
私人:
T*ptr;
};
浮点数组[3]={3.14,2.18,-1};
ptr_包装器get_ptr(void){return array;}
无效使用\u ptr(ptr\u包装器ptr){
对于(int i=0;i<3;++i)
谢谢你的回复,我的朋友。这是一个好主意。不幸的是,我对文档有点困惑,我不太确定如何做你所描述的。任何例子都非常受欢迎!@AstrOne我添加了一个例子