2013-06-14 15 views
6

Używam python do wywoływania metod w udostępnionej bibliotece C++. Mam problem z konwertowaniem tablicy numpy 2D na szyk C++ 2D jako wejście funkcji. Mam stworzony zabawkowy przykład, który pokazuje problem. Zapraszam do kompilacji i wypróbowania!Konwertuj tablicę 2D numpy na C++ short **?

Oto kod python (soexample.py):

# Python imports 
from ctypes import CDLL 
import numpy as np 

# Open shared CPP library: 
cpplib=CDLL('./libsoexample.so') 
cppobj = cpplib.CPPClass_py() 

# Stuck on converting to short**? 
array = np.array([[1,2,3],[1,2,3]]) 
cpplib.func_py(cppobj,array) 

Oto biblioteki C++ (soexample.cpp):

#include <iostream> 

using namespace std; 

class CPPClass 
{ 
    public: 
    CPPClass(){} 

    void func(unsigned short **array) 
    { 
     cout << array[0][0] << endl; 
    } 
}; 

// For use with python: 
extern "C" { 
    CPPClass* CPPClass_py(){ return new CPPClass(); } 
    void func_py(CPPClass* myClass, unsigned short **array) 
    {  
     myClass->func(array);  
    } 
} 

które skompilować za pomocą następującego polecenia:

g++ -fPIC -Wall -Wextra -shared -o libsoexample.so soexample.cpp 

Po uruchomieniu pliku Pythona pojawia się następujący błąd:

Jak prawidłowo poprawić ten niefortunny TypeError?

+1

wierzę krótkie ints c są 16 bity. Domyślnie numpy int, z drugiej strony, ma zazwyczaj 32 bity. Możesz spróbować utworzyć tablicę jako 'tablica = np.array ([[1,2,3], [1,2,3]], dtype = np.uint16)' i zobaczyć, co się stanie. – Jaime

Odpowiedz

4

Możesz użyć 's c_short i POINTER, aby pomóc w konwersji pośredniej. Poniższa funkcja zamienia tablicę numpy na 2darray typu C, który można przekazać do funkcji C, oczekując, że będzie to short **.

def c_short_2darr(numpy_arr): 
    c_short_p = POINTER(c_short) 
    arr = (c_short_p * len(numpy_arr))() 
    for i in range(len(numpy_arr)): 
    arr[i] = (c_short * len(numpy_arr[i]))() 
    for j in range(len(numpy_arr[i])): 
     arr[i][j] = numpy_arr[i][j] 
    return arr 

Uwaga został zmodyfikowany func_py i CPPClass::func wziąć 2 dodatkowych parametrów, szerokość i długość danego panelu. Z tym, CPPClass::func można wydrukować wszystkie elementy tablicy:

// ... 
void CPPClass::func(unsigned short **array, size_t w, size_t h) 
{ 
    for(size_t i = 0; i < w; ++i) 
    { 
     for(size_t j = 0; j < h; ++j) 
      cout << array[i][j] << ", "; 
     cout << '\n'; 
    } 
} 
// ... 
void func_py(CPPClass *myClass, 
      unsigned short **array, 
      size_t w, size_t h) 
{ 
    myClass->func(array, w, h); 
} 

Z tej funkcji pomocnika określonym dodaje powinien teraz działać:

>>> arr = numpy.array([ [1,2,3], [4,5,6] ]) 
>>> arr 
array([[1, 2, 3], 
     [4, 5, 6]]) 
>>> cpplib.func_py(cppobj, c_short_2darr(arr), 2, 3) 
1, 2, 3, 
4, 5, 6, 
0 
+0

Dzięki! To działało idealnie. Mam inne podobne pytanie, które może mi pomóc: http://stackoverflow.com/questions/17138054/return-c-double-to-python – dillerj

Powiązane problemy