Reputation: 21
I am using the ctypes at python3.8 to call C++ function, the function parameter is an array, and its returns to an array as well. So I create the python list first, then convert it to C++ array to call the function.
ll = ctypes.cdll.LoadLibrary
lib = ll('./ct.so')
nums = [0, 1, 2, 3]
arr = (ctypes.c_int * len(nums))(*nums)
nums2 = lib.method01(arr)
As you can see, nums
is a python list, and I convert it to C++ array by using ctypes, get arr
. Then I get a C++ array nums2
by calling lib.method01(arr)
.
Since nums2
is a C++ array, so the print(nums2)
get the result like this: __main__.c_int_Array_4
, which is not a python array. So is there anything can do to transfer c++ array to python array?
Thanks
Upvotes: 2
Views: 723
Reputation: 177755
Just call list(nums2)
. Example:
>>> from ctypes import *
>>> nums = [0,1,2,3]
>>> arr = (c_int*4)(*nums)
>>> arr
<__main__.c_long_Array_4 object at 0x00000217CE89F7C8>
>>> list(arr)
[0, 1, 2, 3]
Note this also works if your API returns a pointer as well, but needs string slicing since the total length must also be known:
>>> p = cast(arr,POINTER(c_int))
>>> p
<__main__.LP_c_long object at 0x00000217CE89F948>
>>> p.contents
c_long(0)
>>> p[0]
0
>>> p[3]
3
>>> p[4] # undefined behavior...past end of array.
0
>>> p[:4] # slice to known size
[0, 1, 2, 3]
FYI, as @user2357112 points out, slicing is ~4.5x faster:
In [1]: from ctypes import *
In [2]: nums = list(range(5000))
In [3]: arr = (c_int*5000)(*nums)
In [4]: %timeit list(arr)
454 µs ± 9.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [5]: %timeit arr[:]
107 µs ± 2.32 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Upvotes: 2
Reputation: 281151
Slice it:
as_list = nums2[:]
This runs faster than calling list
. (I don't think the slice-returns-a-list behavior is documented anywhere in the ctypes docs.)
Upvotes: 0