python使用C函数返回的指针

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python使用C函数返回的指针相关的知识,希望对你有一定的参考价值。

有一个DLL文件,其中的pInput函数返回一个char*,指向一个缓冲区。
如何用python实现调用pInput函数,并向char*指向的内存区域写入数据?
就像是在C当中:char *p = pInput(); p[39] = '\n'; 这种。
我知道应该用ctypes库,网上也有返回结构体指针的实现。
我的问题类似,但是把结构体换成数组网上就没有结论了。如果缓冲区大小是已知的呢?

参考技术A int* GrabImage();
int GetPixel(int* image, int x, int y);
void SetPixel(int* image, int x, int y, int color);追问

粘贴错东西了?您的回答与题目无关。

参考技术B manage_new_object返回类的动态对象,要返回简单的指针,把manage_new_object改为return_xxx_pointer,具体名字记不得了,反正有这个模板,查阅boost文档吧。追问

哇塞找到大神了。。。可惜完全看不懂。。。我刚学python。
DLL.pInput.restype = ctypes.POINTER(ctypes.c_char * 40)
buf = DLL.pInput().contents
buf[39] = b'\n'

已经找到实现方式(上面的就是),财富值送给大神了。

本回答被提问者采纳

使用 Python、C++ 和 pybind11 返回和传递原始 POD 指针(数组)

【中文标题】使用 Python、C++ 和 pybind11 返回和传递原始 POD 指针(数组)【英文标题】:Returning and passing around raw POD pointers (arrays) with Python, C++, and pybind11 【发布时间】:2018-02-26 05:45:34 【问题描述】:

我有一个返回原始 float 指针的 C++ 函数,以及另一个接受原始 float 指针作为参数的 C++ 函数。比如:

float* ptr = something;
float* get_ptr(void)  return ptr; 
void use_ptr(float* ptr)  do_work(ptr); 

我希望能够使用 Python 传递指针。像这样的:

import my_native_functions as native
ptr = native.get_ptr()
native.use_ptr(ptr)

我正在使用 pybind11 创建我的本机 python 模块,但我不知道如何为 get_ptr() 函数创建绑定。如果我只是执行以下操作:

PYBIND11_MODULE(my_native_functions, m)

    m.def("get_ptr", &get_ptr);
    m.def("use_ptr", &use_ptr);

get_ptr() 函数返回 Python Float 对象。我想这是有道理的,因为 python 中没有指针类型。但是,因为现在这是一个简单的Float,所以当我调用use_ptr() 函数并在C/C++ 中迭代指针时,只有数组的第一个元素是正确的。其余都是垃圾。为了解决这个问题,在 C++ 中,我必须将我的指针投射到/来自std::size_t。通过这样做,一切正常。

但是,我想问一下:是否有一种“正确的方法”可以在不使用 pybind11 向/从std::size_t 转换的情况下实现上述目标?

如果你好奇我为什么这样做: 我明白我所做的不是类型安全的。此外,我从不触摸 Python 端的指针/整数。我只是从一个本机模块中检索它并将其传递给另一个。另外,我不能将指针转换为某种 numpy 视图,因为指针并不总是在 CPU 上。有时我想传递 CUDA 指针。除非我复制数据(我不想这样做),否则不可能从 CUDA 指针创建 py::array_t

谢谢。

【问题讨论】:

【参考方案1】:

如here 所述,将原始指针包装在自定义的“智能”指针类中(只是假装真的很智能)。你可以在这个类中添加一些额外的信息,比如数组元素的大小和元素的数量。这将使它成为 C++ 端的通用数组描述符(但不是 Python 端,因为您没有将原始指针暴露给 Python)。

对于一个更简单的选项,只需将指针包装在任何旧类中,以便将其隐藏在 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);

【讨论】:

感谢您的回复我的朋友。那是一个好主意。不幸的是,我对文档有点困惑,我不太确定如何做你所描述的。任何示例都非常受欢迎! @AstrOne 我加了一个例子

以上是关于python使用C函数返回的指针的主要内容,如果未能解决你的问题,请参考以下文章

使用 CFFI 从 Python 传递指向 C 函数的指针的最佳方法

使用 Python、C++ 和 pybind11 返回和传递原始 POD 指针(数组)

我可以像在 c++ 中使用指针一样修改函数中的变量而不在 python 中返回吗

从 Python (ctypes) 指向 C 以保存函数输出的指针

Python函数指针具有不同的参数

在 Python/ctypes 中的结构内取消引用 C 函数指针