numpy.ctypeslib:C 代码将传递的 numpy 数组中的所有其他索引视为零

numpy.ctypeslib: C code sees every other index as zero in passed numpy array

Debian 版本:WSL 上的 Buster (10)

numpy 版本:1.20.1

python版本:3.7.3

gcc 版本:8.3.0

我正在尝试将一个 numpy 数组传递给一个用 C 编写的函数。C 函数认为该数组的长度是其两倍,而其他所有条目均为零。我不知道为什么会这样,也找不到任何人 运行 遇到类似问题的实例。

这里是function.c的内容:

#include <stdio.h>

void function(int* array, int size) {

        int i;

        for (i = 0; i < size; ++i) {
                printf("i = %d, array value = %d \n", i, array[i]);
        }
}

int main() {
        return 0;
}

我正在使用以下步骤将 C 代码编译成 .so 文件:

gcc -c -fPIC function.c -o function.o
gcc function.o -shared -o function.so

这是 python 文件 main.py,它使用简单的数组调用 C 代码。

import numpy as np
import ctypes

c_int_array = np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags='C_CONTIGUOUS')

lib = np.ctypeslib.load_library('function.so', '.')
lib.function.argtypes = [c_int_array, ctypes.c_int]

array = np.array([1,2,3,4])

lib.function(array, len(array))

当我 运行 main.py 文件时,我得到以下结果。

i = 0, array value = 1
i = 1, array value = 0
i = 2, array value = 2
i = 3, array value = 0

下面是我将数组的大小乘以二时发生的情况。 lib.function(array, 2*len(array))

i = 0, array value = 1
i = 1, array value = 0
i = 2, array value = 2
i = 3, array value = 0
i = 4, array value = 3
i = 5, array value = 0
i = 6, array value = 4
i = 7, array value = 0

将 numpy 数组从 python 传递到 C 代码时似乎出现了问题。其他索引为零是很奇怪的。

知道是什么原因造成的吗?如何解决?像往常一样,我可能正在做一些明显而愚蠢的事情,但我似乎无法弄清楚。我尽量让这道题的代码尽可能简单。

正如我最初在评论中假设的那样,问题是由这些行引起的:

# Python
c_int_array = np.ctypeslib.ndpointer(dtype=np.int64, ndim=1, flags='C_CONTIGUOUS')
// C
void function(int* array, int size)

这里的Python指针是一个指向64位整数的指针,但是C函数接受的是一个指向32位整数的指针,正好是64位整数的两倍.

有两种方法可以解决这个问题:

  • 从 Python
  • 传递指向 np.int32 的指针
  • 在 C 中接受指向 long longint64_t 的指针:
    #include <stdint.h>
    void function(int64_t* array, int size)