pybind11指针参考

发布于 2025-02-13 09:56:07 字数 1433 浏览 2 评论 0原文

我正在尝试使用Python中的C ++函数,该功能将指针作为参数。 对于立面,我在Python中使用Pybind11和CTYPE,以创建指针。

但是,我在Python中获得的地址并不等于C ++中的Adress。 我确实需要稍后在项目的变量的地址,我无法通过返回来获得它,因为该功能已经在返回其他内容。

C ++函数

  void myFunc(double* ptr, double value)
  {
      *ptr = value;

      std::cout << "ptr value:\t\t" << *ptr << std::endl;
      std::cout << "ptr adress:\t\t" << ptr << std::endl;
  };

Pybind代码

m.def("myFunc",
    [](double* ptr,
        double value) {
            myFunc(ptr, value);
    }, "funtion to test stuff out");

Python代码

ptr_value = ctypes.c_double()
ptr_addressof = ctypes.addressof(ptr_value)
ptr_object_pointer = pointer(ptr_value)
ptr_pointer = ctypes.cast(ptr_object_pointer, ctypes.c_void_p).value
print(f'python ptr using addressof(ptr_value):\t\t{ptr_addressof}')
print(f'python adress using ctypes.cast:\t\t{ptr_pointer}')
print(f'python ptr object using pointer(ptr_value):\t{ptr_object_pointer}')

value = 14.0
myFunc(ptr_addressof, value)

输出

python ptr using addressof(ptr_value):          2784493684616
python adress using ctypes.cast:                2784493684616
python ptr object using pointer(ptr_value):     <__main__.LP_c_double object at 0x0000028850C1C8C0>
ptr value:              14
ptr adress:             000000CC2D3EE490

如何在C ++和Python中获得相同的地址?

I'm trying to use a c++ function, that takes a pointer as an argument, in python.
For the facade I'm using pybind11 and ctypes in python in order to create pointers.

However the adress I'm getting in python isn't equal to the one in c++.
I do need the adress of a variable later in the project and i cant get it by return, since the function is already returning something else.

c++ function

  void myFunc(double* ptr, double value)
  {
      *ptr = value;

      std::cout << "ptr value:\t\t" << *ptr << std::endl;
      std::cout << "ptr adress:\t\t" << ptr << std::endl;
  };

pybind code

m.def("myFunc",
    [](double* ptr,
        double value) {
            myFunc(ptr, value);
    }, "funtion to test stuff out");

python code

ptr_value = ctypes.c_double()
ptr_addressof = ctypes.addressof(ptr_value)
ptr_object_pointer = pointer(ptr_value)
ptr_pointer = ctypes.cast(ptr_object_pointer, ctypes.c_void_p).value
print(f'python ptr using addressof(ptr_value):\t\t{ptr_addressof}')
print(f'python adress using ctypes.cast:\t\t{ptr_pointer}')
print(f'python ptr object using pointer(ptr_value):\t{ptr_object_pointer}')

value = 14.0
myFunc(ptr_addressof, value)

output

python ptr using addressof(ptr_value):          2784493684616
python adress using ctypes.cast:                2784493684616
python ptr object using pointer(ptr_value):     <__main__.LP_c_double object at 0x0000028850C1C8C0>
ptr value:              14
ptr adress:             000000CC2D3EE490

How do I get the same adress in c++ and python?

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

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

发布评论

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

评论(3

孤单情人 2025-02-20 09:56:07

仅CTYPES的Solutiom:

test.cpp

#include <stdio.h>

#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

extern "C"
API void myFunc(double* ptr, double value) {
    *ptr = value;
};

test.py

import ctypes as ct

dll = ct.CDLL('./test')
dll.myFunc.argtypes = ct.POINTER(ct.c_double), ct.c_double
dll.myFunc.restype = None

val = ct.c_double()
dll.myFunc(val, 14)
print(val.value)

输出:

14.0

A ctypes-only solutiom:

test.cpp

#include <stdio.h>

#ifdef _WIN32
#   define API __declspec(dllexport)
#else
#   define API
#endif

extern "C"
API void myFunc(double* ptr, double value) {
    *ptr = value;
};

test.py

import ctypes as ct

dll = ct.CDLL('./test')
dll.myFunc.argtypes = ct.POINTER(ct.c_double), ct.c_double
dll.myFunc.restype = None

val = ct.c_double()
dll.myFunc(val, 14)
print(val.value)

Output:

14.0
坏尐絯 2025-02-20 09:56:07

pybind11中的指针功能参数不起作用。

所有“ Pointer-To-T”和“ Referent to To-T”函数参数均已转换,以使Python仅看到PLAINT。因此,如果您调用

x = 0.123
myFunc(x, 42)

Python,请看到一个接受两个float参数的函数,并且C ++实现在 *ptr = val分配之前,请看到*ptr == 0.123

void myFunc(double* ptr, double value)
{
    std::cout << "Before:\t\t" << *ptr << std::endl;
    *ptr = value;
    std::cout << "After:\t\t" << *ptr << std::endl;
};

Before:   0.123
After:    42

C ++函数中的指针指向python x对象(通常是不可能的,因为Python的float不一定与C ++'S double是相同的东西),但在呼叫期间由PYBIND11机械持有的C ++表示。对该C ++对象的修改不会传播回Python。

为了通过C ++和Python之间的指针,您需要将它们包裹在某种类中,以将其隐藏在PYBIND11机械中。

Pointer function parameters in pybind11 don't work this way.

All "pointer-to-T" and "reference-to-T" function parameters are transformed such that Python only sees plain T. So if you call

x = 0.123
myFunc(x, 42)

Python sees a function that accepts two float arguments, and the C++ implementation sees *ptr == 0.123 before *ptr = val assignment.

void myFunc(double* ptr, double value)
{
    std::cout << "Before:\t\t" << *ptr << std::endl;
    *ptr = value;
    std::cout << "After:\t\t" << *ptr << std::endl;
};

Before:   0.123
After:    42

The pointer in the C++ function points not to the Python x object (it would not be generally possible, because Python's float is not necessarily the same thing as C++'s double), but to its C++ representation held by pybind11 machinery for the duration of the call. Modifications to that C++ object are not propagated back to Python.

In order to pass pointers between C++ and Python, you need to wrap them in some sort of class that hides them from the pybind11 machinery.

兮颜 2025-02-20 09:56:07

我能够解决这个问题。这只是我思考过程中的一个错误。
Pybind现在看起来像是这样的

m.def("myFunc",
    [](double value) {
            void *pointer;
            otherValue = myFunc(&pointer, value);
        return std::make_tuple(pointer, otherValue);
    }, "funtion to test stuff out");

说明,这有点类似于我以前尝试过的东西。我很困惑,因为在python中打印指针变量时的输出是Adress XXX的对象。但是,地址并不代表C ++的地址,而是python中变量的地址。

现在,我可以调用其他CPP功能,这些功能将指针作为输入,并以返回的指针作为参数,并且效果很好。

C ++函数将指针指针作为参数,然后更改输入指针所指的地址的值,将其引用到程序以后将在程序中使用的对象。

  void myFunc(void **ptr, double value)
  {
      *ptr = &value;
  }; 

I was able to fix the Issue. It was just an error in my thinking process.
Pybind now looks like this

m.def("myFunc",
    [](double value) {
            void *pointer;
            otherValue = myFunc(&pointer, value);
        return std::make_tuple(pointer, otherValue);
    }, "funtion to test stuff out");

Note that this is kinda similar to something i was trying before. I was confused because the output when printing the pointer variable in python was object at adress xxx. The adress however didn't represent the c++ adress but the adress of the variable in python.

Now i can call other cpp functions that are taking a pointer as an input with the returned pointer as an argument and it works just fine.

The c++ function takes a pointer pointer as an argument and then changes the value of the adress, that the input pointer is refering to, to an object that will be used later in the program.

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