1

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.

2
  • 3
    I think it's because in dtype=np.int64 the type is 64 bits wide, but your function accepts int* array - a pointer to 32-bit integers. Commented Mar 1, 2021 at 13:59
  • Yup that was it. I changed the numpy array to dtype=np.int32 and the problem went away. Thank you! Commented Mar 1, 2021 at 14:02

1 Answer 1

2

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)
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.