简体   繁体   中英

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

Debian version: Buster (10) on WSL

numpy version: 1.20.1

python version: 3.7.3

gcc version: 8.3.0

I'm trying to pass a numpy array to a function written in C. The C function sees the array as being twice as long with every other entry being zero. I have no idea why this is happening and couldn't find any instances of someone running into a similar problem.

Here's the contents of 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;
}

I'm compiling the C code into an .so file using the following steps:

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

Here's the python file, main.py , that calls the C code with a simple array.

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))

When I run the main.py file, I get the following result.

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

Here's what happens when I multiply the size of the array by two. 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

There seems to be an issue that occurs when passing the numpy array from python to the C code. Ever other index being zero is very strange.

Any idea what's causing this and how this can be fixed? As usual, I'm probably doing something obvious and stupid but I can't seem to figure this out. I tried to make the code for this question as simple as reasonable.

As I initially hypothesised in my comment, the issue was caused by these lines:

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

Here, the Python pointer is a pointer to a 64-bit integer, but the C function accepts a pointer to a 32-bit integer, which is exactly twice as short as the 64-bit one.

There are two ways to solve this:

  • Pass a pointer to np.int32 from Python
  • Accept a pointer to long long or int64_t in C:
     #include <stdint.h> void function(int64_t* array, int size)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM