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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With