将numpy数组的地址写入文件,然后通过ctypes在C++中打开它



我想知道是否可以通过例如ctypeslib.ndpointer或类似的方式在文件中写入numpy数组的地址,然后在C++函数中打开该文件,该函数也通过同一python进程中的ctypes调用,读取该地址,将其转换为例如C++double array

这一切都将发生在同一个python进程中

我知道可以将它作为函数参数传递,这很有效,但这不是我需要的。

这就是代码的样子,不要介意语法错误:

test.py
with open(path) as f:
f.write(matrix.ctypes.data_as(np.ctypeslib.ndpointer(dtype=np.float64, ndim=2, flags='C_CONTIGUOUS')))

和cpp:

void function()
{
... read file, get address stored into double* array;
e.g. then print out the values
}

我哪里错了?

我在一个项目中工作,我们将np数组写入一个文件,然后在cpp中读取该文件,这是浪费。我想试着把它调整为写,以后只读这个地址。发送ndpointer或其他东西作为函数参数是行不通的,因为这需要编辑项目的大部分内容。

我认为一旦python程序终止,np.array的数据就会丢失,因此一旦程序结束,您将无法访问其内存位置。

不幸的是,我不知道如何使用ctypes,但只使用C-API扩展。使用它,您可以直接从c访问python变量。它由指针表示,因此您可以访问任何python对象的地址(因此也可以访问ndarrays(。

在python中,你会写:

import c_module
import NumPy as np
...
a = np.array([...])
#generate the numpy array
...
c_module.c_fun(a)

然后在您的c++代码中,您将收到内存地址

static PyObject* py_f_roots(PyObject* self, PyObject* args) {
PyObject *np_array_py;
if (!PyArg_ParseTuple(args, "OO", &np_array_py))
return NULL;
//now np_array_py points to the memory cell of the python numpy array a
//if you want to access it you need to cast it to a PyArrayObject *
PyArrayObject *np_array = (PyArrayObject *) np_array_py;
//you can access the data
double *data = (double *) PyArray_DATA(np_array);

return Py_None;
}

numpy c API 的文档

c python扩展参考手册

如果Python和C代码在同一进程中运行,那么您从Python编写的地址在C中是有效的

测试.py

import ctypes as ct
import numpy as np
matrix = np.array([1.1,2.2,3.3,4.4,5.5])
# use binary to write the address
with open('addr.bin','wb') as f:
# type of pointer doesn't matter just need the address
f.write(matrix.ctypes.data_as(ct.c_void_p))
# test function to receive the filename
dll = ct.CDLL('./test')
dll.func.argtypes = ct.c_char_p,
dll.func.restype = None
dll.func(b'addr.bin')

test.c

#include <stdio.h>
__declspec(dllexport)
void func(const char* file) {
double* p;
FILE* fp = fopen(file,"rb");  // read the pointer
fread(&p, 1, sizeof(p), fp);
fclose(fp);
for(int i = 0; i < 5; ++i)    // dump the elements
printf("%lfn", p[i]);
}

输出:

1.100000
2.200000
3.300000
4.400000
5.500000

最新更新