The problem was that I had a C ++ vector and I needed to convert it to a numpy array. The vector was from an external library. All I could do was add an extra function to the source code and recompile it again into the original DLL. The idea was that I import the function using ctypes and then call it with the void pointer pointer and let the C ++ function insert a vector pointer. Here the first problems began. I was able to send the pointer back to Python, explicitly allocating memory. I not only need to use
myVec = new vector<T>
even for int pointer i needed to use
myIntP = new int
Just do
x = 10
int* myIntP = &x
*pythonIntPP = myIntP
. Python, .
**pythonIntPP = x
.
?
, :
-, ++ DLL, **.
from ctypes import *
lib = cdll.LoadLibrary(r"C:\path\to.dll")
gvp = lib.GetVectorPointer
gvp.restype = c_int
gvp.argtypes = [POINTER(c_void_p), POINTER(c_int)]
voidPP = pointer(c_void_p())
sizeP = pointer(c_int())
gvp(voidPP, sizeP)
Python, Cython. , cdef, DLL ( pyd) Python.
Cython
import numpy as np
cimport numpy as np
from libcpp.vector cimport vector
ctypedef vector[T] Vec
ctypedef myVec* VecP
ctypedef VecP* VecPP
arr = np.empty(1, dtype=np.uint8)
def allocate_arr(size):
arr.resize(size, refcheck=False)
cdef public int vec_to_numpy(void** voidPP):
cdef VecP vecp= <VecP>ppVoid[0]
cdef int size = vecp[0].size()
cdef np.ndarray[T, ndim=1] data = arr # arr needs to be allocated
cdef int i
for i in range(size):
data[i] = vecp[0][i]
return 0
Python
lib = windll.LoadLibrary(r"C:\path\to\module.pyd")
v2n = lib.vec_to_numpy
v2n.restype = c_int
v2n.argtypes = [POINTER(c_void_p)]
import module
module.allocate_arr(sizeP)
v2n(voidPP)
module.arr
TIP:
Cython .
( ).
cdef void emit_pragma 'foo ();\n#pragma comment(linker, "/export:vec_to_numpy=vec_to_numpy")\nstatic void unused' ():pass
( __stdcall, ).
cdef int vec_to_numpy 'unused;\nextern "C" __declspec(dllexport) public int __stdcall vec_to_numpy' (void** voidPP):
?
, Python, ? cdef Python .