How to convert a C ++ vector to a numpy array or how to move a vector pointer back and forth between C ++, Cython and Python?

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)] # we need the vector pointer and size
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) # allocate first
v2n(voidPP) # send the vector pointer to the Cython function

module.arr # this is the numpy array with the vector data

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 .

+4

All Articles