简体   繁体   中英

python ctypes - passing numpy array - odd output

I'm using ctypes and I'm passing a ndarray to a c-function. It gives me a odd output behavior. Heres some code:

C-Function:

int foo(int * foo,int N){
for(int i=0;i<N;i++){
    cout << "i " << i  << " "<< foo[i]  << endl;
    }
return 0;
}

Python:

from ctypes import *
import numpy as np
bar = cdll.LoadLibrary(".../libtest.so")
N = c_int(10)
check = np.ones(10, dtype=int)
print check
bar.foo(c_int(check.ctypes.data),N)

Output:

[1 1 1 1 1 1 1 1 1 1]
i:0 out:1
i:1 out:0
i:2 out:1
i:3 out:0
i:4 out:1
i:5 out:0
i:6 out:1
i:7 out:0
i:8 out:1
i:9 out:0

Should be all ones right? :)

I' compiling with

g++ -g -c -fPIC -O0  pythagoras.cpp 
g++ -shared -Wl,-soname=libtest.so -o libtest.so  pythagoras.o 

Anyone any ideas? I'm searching the failure now for at least 1hr and I'm having no idea what the solution is(probably something stupid)

Thanks in advance!

Setting the dtype to a Python int will use a C long . If you're on a 64-bit platform (other than Windows), that's a 64-bit data type, which explains the interleaved 0s. You can check this by setting dtype=np.int32 vs dtype=np.int64 .

Secondly, check.ctypes.data is a Python int representing a C void * pointer. Passing it as c_int isn't correct. At a minimum, use c_void_p , and define argtypes :

from ctypes import *
import numpy as np

bar = CDLL('.../libtest.so')
bar.foo.argtypes = [c_void_p, c_int]

check.ctypes defines the _as_parameter_ ctypes hook, which returns an instance of c_void_p :

N = 10
check = np.ones(N, dtype=np.int32)
print check
bar.foo(check.ctypes, N)

You can be more specific with check.ctypes.data_as , or by defining a type with np.ctypeslib.ndpointer .

By the way, foo is a C++ function, not C. You must have used extern "C" . Otherwise the exported name would be mangled.

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