我正在尝试获取 PyObject* 中保存的数据的内存地址(具体来自 Python.h 3.8.2),以便我可以对缓冲区执行 memcpy。我只能弄清楚如何将数据从对象中复制出来,但仅靠获取指针就什么都没有了。假设我有这个对象 data
...
PyObject* data = PyLong_FromLong(100L);
到目前为止,似乎我将这些数据转移到缓冲区的唯一选择是将其复制出来,然后使用临时变量的地址执行 memcpy ...long temp = PyLong_AsLong(data);
memcpy(buffer, &temp, 8);
这已经完成了成千上万次,所以我认为如果我能够获得数据的内存地址并直接将其复制到我的缓冲区中会更快......memcpy(buffer, data->address_to_data(), 8)
而不是将额外的拷贝复制到临时变量。有谁知道我是否/如何从 PyObject* 包装器获取长值的内存地址?
感谢帮助!
最佳答案
这似乎是一个 X-Y 问题(即您认为您需要在 C 级别从一堆 Python 对象中提取数据,但实际上您会受益于拥有一个公开所有数据的 Python 对象)。
一个 Python int
可以存储(几乎)任意大的数字:
>>> 1000**1000 # creates a very big int
即它不在内部存储为 C long。 Internally it is stored作为大小为 ob_digits
的整数数组 ( ob_size
)这是一种稍微奇怪的格式,对您没有多大用处。但是,如果您真的想复制它,您会将对象指针设置为 PyLongObject*
然后做一个 memcpy(&dest, my_int->ob_digit, sizeof(digit)*abs(my_int->ob_size));
.我建议不要这样做,因为您很难使用这些数据。显然,这仅适用于您知道自己拥有 Python
int
的情况。 .对于“通用 PyObject*
”,这不起作用,因为通用 PyObject*
几乎可以包含任何数据。这包括需要所有权和/或引用计数的指针(这尤其适用于任何包含其他 PyObject
的 PyObject
)。我认为你真正想要的是将你的数据存储在一个大的 C 整数数组中。这可以通过
array.array
来完成, 或 numpy.array
,或各种其他类。在 C 级别,这些对象支持 the buffer protocol他们将内部数组暴露给 C,允许从 C 访问、复制、操作每个值。
一些未经测试的快速说明性代码:
Py_Buffer view;
view.format = "l"; // request an array of longs
if (PyObject_GetBuffer(obj, &view, PyBUF_CONTIG | PyBUF_FORMAT | PyBUF_WRITABLE ) == -1) {
// failed
return NULL;
}
// you want to check that view.ndim == 1 (for a simple 1D array)
long* data = (long*)view.buf;
// At this point you can access data as a C array of length view.len
// When you've finished;
PyBuffer_Release(view);
关于python - 如何获得指向通用 PyObject* 内数据的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69231376/