pybind11 如何将指针转换为 std::size_t 或从 std::size_t 转换指针?

发布于 2025-01-12 15:03:31 字数 1280 浏览 1 评论 0原文

我从 Stackoverflow 的一个问题中发现了一个问题。描述如下:

我有一个返回原始浮点指针的 C++ 函数,以及另一个接受原始浮点指针作为参数的 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 进行转换?

以上是来自AstrOne问题的整个问题描述:使用 Python、C++ 和 pybind11 返回并传递原始 POD 指针(数组)

我的问题是“为了解决这个问题,在C++中,我必须将指针转换为std::size_t”,这个转换应该如何完成?这里可以给我一个例子或更详细的解释吗?我不太明白。

I see a problem from one Stackoverflow question. It is described below:

I have a C++ function which returns a raw float pointer, and another C++ function which accepts a raw float pointer as an argument. Something like:

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

I want to be able to pass around pointers using Python. Something like this:

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

I am using pybind11 to create my native python module but I don't know how to create the bindings for the get_ptr() function. If I just do the following:

PYBIND11_MODULE(my_native_functions, m)
{
    m.def("get_ptr", &get_ptr);
    m.def("use_ptr", &use_ptr);
}

the get_ptr() function returns a Python Float object. I guess this makes sense because there are no pointer types in python. However, because this is now a simple Float, when I call the use_ptr() function and iterate over the pointer in C/C++, only the first element of the array is correct. The rest are garbage. To fix this, in C++, I have to cast my pointer to/from std::size_t. By doing this, everything works just fine.

However, I would like to ask: Is there a "right way" of achieving the above without the casting to/from std::size_t with pybind11?

The above is the whole problem description that comes from AstrOne's question:Returning and passing around raw POD pointers (arrays) with Python, C++, and pybind11.

My question is "To fix this, in C++, I have to cast my pointer to/from std::size_t", how should this cast be done? Can here give me a example or more detailed explanation? I don't quite understand.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

童话里做英雄 2025-01-19 15:03:31

float* 类型替换为 std::uintptr_t。请参阅下文,

#include <cstdint>

float* ptr = something;
std::uintptr_t get_ptr() { return reinterpret_cast<std::uintptr_t>(ptr); }
void use_ptr(std::uintptr_t ptr) { do_work(reinterpret_cast<float*>(ptr)); }

现在不会向 pybind11 公开任何指针类型。这里所做的只是将指针类型转换为整型,这在二进制表示中没有任何区别。

另外:在大多数平台上 std::size_t 都可以。根据 cppref

在许多平台上(例外是具有分段寻址的系统)std::size_t 可以安全地存储任何非成员指针的值,在这种情况下它与 std::uintptr_t 同义。

Replace the float* type with std::uintptr_t. See below

#include <cstdint>

float* ptr = something;
std::uintptr_t get_ptr() { return reinterpret_cast<std::uintptr_t>(ptr); }
void use_ptr(std::uintptr_t ptr) { do_work(reinterpret_cast<float*>(ptr)); }

No pointer types will be exposed to pybind11 now. What is doing here is just cast a pointer type to a integral type, which has no difference in binary representation.

Aside: std::size_t would be Ok in most platforms. As per cppref:

On many platforms (an exception is systems with segmented addressing) std::size_t can safely store the value of any non-member pointer, in which case it is synonymous with std::uintptr_t.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文