目前,我尝试过:
import ctypes as ct
import numpy as np
arr = np.array([
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
],
[
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]
]
])
arr_c = np.ascontiguousarray(arr)
lib = ct.CDLL("path/to/share_object.so")
_effect_array = lib.effect_array
_effect_array.argtypes = [ct.POINTER(ct.POINTER(ct.POINTER(ct.c_int))), ct.c_int, ct.c_int, ct.c_int]
_effect_array.restype = None
rows, cols, depth = arr.shape
t_ptr = (ct.POINTER(ct.POINTER(ct.c_int)) * rows)()
for i in range(rows):
t_ptr[i] = (ct.POINTER(ct.c_int) * cols)()
for j in range(cols):
t_ptr[i][j] = arr_c[i][j].ctypes.data_as(ct.POINTER(ct.c_int))
print("Original array =")
print(arr_c)
print()
_effect_array(t_ptr, rows, cols, depth)
print("Array after pass to function =")
print(arr_c)
这导致了一个输出:
Original array =
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]]
Array after pass to function =
[[[ 2 4 3 4]
[10 12 7 8]
[18 20 11 12]]
[[26 28 15 16]
[34 36 19 20]
[42 44 23 24]]]
我想发生的事情是:
Original array =
[[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
[[13 14 15 16]
[17 18 19 20]
[21 22 23 24]]]
Array after pass to function =
[[[ 2 4 6 8]
[10 12 14 16]
[18 20 22 24]]
[[26 28 30 32]
[34 36 38 40]
[42 44 46 48]]]
我不确定为什么C函数无法连续访问前两个以外的元素。我的理解是,我当前的尝试可以访问数组的开始,并且应该能够像在此C示例中一样通过数组的其余部分迭代:
#include <stdio.h>
#include <stdlib.h>
void effect_array(int ***ptr, int rows, int cols, int depth)
{
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
for(int k = 0; k < depth; k++)
{
ptr[i][j][k] *= 2;
}
}
}
}
int main()
{
int arr[2][2][2] = {
{
{1,2},
{3,4}
},
{
{5,6},
{7,8}
}
};
int arr2[5];
int *p = arr2;
int ***ptr = (int ***)malloc(2 * sizeof(int **));
for(int i = 0; i < 2; i++)
{
ptr[i] = (int **)malloc(2 * sizeof(int *));
for(int j = 0; j < 2; j++)
{
ptr[i][j] = &arr[i][j][0];
}
}
printf("Print array before:\n");
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
for(int k = 0; k < 2; k++)
{
printf("%d ", arr[i][j][k]);
}
printf("\n");
}
printf("\n");
}
effect_array(ptr, 2, 2, 2);
printf("Print array after:\n");
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
for(int k = 0; k < 2; k++)
{
printf("%d ", arr[i][j][k]);
}
printf("\n");
}
printf("\n");
}
for(int i = 0; i < 2; i++) free(ptr[i]);
free(ptr);
return 0;
}
这也基于关于审查问题的讨论。
任何人都非常感谢。
在您的原始Python代码中,dtype
是arr
np.int64
dtype=np.int32
和指针数学直接传递多维Numpy数组。
示例:
-test.c
int*
-test.py
#include <stdio.h>
__declspec(dllexport)
void affect_array(int *ptr, int rows, int cols, int depth) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
for(int k = 0; k < depth; k++) {
printf("%d ", ptr[i*rows*cols + j*cols + k]);
}
printf("\n");
}
}
for(int i = 0; i < rows; i++) {
for(int j = 0; j < cols; j++) {
for(int k = 0; k < depth; k++) {
ptr[i*cols*depth + j*depth + k] *= 2;
}
}
}
}
输出:
import ctypes as ct
import numpy as np
arr = np.array([[[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]],
[[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]]], dtype=np.int32)
lib = ct.CDLL('./test')
affect_array = lib.affect_array
affect_array.argtypes = ct.POINTER(ct.c_int), ct.c_int, ct.c_int, ct.c_int
affect_array.restype = None
rows, cols, depth = arr.shape
print('Original array =')
print(arr)
print()
affect_array(arr.ctypes.data_as(ct.POINTER(ct.c_int)), rows, cols, depth)
print('Array after pass to function =')
print(arr)