我正在探索使用SWIG包装c ++类并从numpy传递数据
我可以使用以下typemap成功传入1d数组
(float*, IN_ARRAY1, int DIM1)
在编译时不知道数组的大小,所以我不能使用类型映射
(float, IN_ARRAY2[DIM1][DIM2])
numpy.i帮助建议使用
(float*, IN_ARRAY2, int DIM1, int DIM2)
但是我的c ++类需要 - 指向浮点数的指针
void Initialise(float** buffer, long dim1, long dim2)
使用float * IN_ARRAY2类型的地图我需要交错我的两个维度吗?我希望不是,有没有人成功地做到了这一点,你做了什么。
答案 0 :(得分:2)
你似乎无法将float **传递给numpy C API,因为它们不是先验的兼容内存表示。
在numpy中,数组中的数据必须位于一个连续的内存区域中(可能存在漏洞,但它们必须位于一个块中,例如由malloc分配):
data -> | - | - | - | ..... | - | # this is allocated in one block
a0 a1 a2 an
使用float **时,你的内存模型可能是:
float** a;
int n = 10, m = 20; // n,m matrix
a = malloc(sizeof(*a) * n) // ten rows
for (int i=0; i < n; ++i) {
a[i] = malloc(sizeof(*a[i]) * m); // one row of 29 items
}
那就是记忆:
a -> | a[0] | -> | a[0][0] | a[0][1] | a[0][2] |
| a[1] | -> | a[1][0] | ....
这实际上几乎总是一种糟糕的数值计算格式,因为你不能在一个块中传递数据(对于内存局部性等不好......),而且几乎每个值得盐的数字库都使用这种格式。参见例如this获得解释。
尽管如此,假设您无法修改代码,您可以轻松地将单个块格式转换为float **格式而无需复制(相反的情况不可能):
void convert(float *in, int n, int m, float ***out)
{
float **data;
int i;
data = malloc(sizeof(*data) * n);
for(i = 0; i < n; ++i) {
data[i] = in + i * m:
}
*out = data;
}
你将此功能称为
float **a;
convert((float*)numpy_data, n, m, &a);
Initialise(a, n, m);
实际上最好不要从API POV中分配函数,这只是为了让您在两种格式之间进行转换。
答案 1 :(得分:0)
无论如何,如果将数组作为参数传递,则将指针传递给数组的第一个元素。你必须知道数组维度才能使用它。