2013-06-14 5 views
6

So verwende ich Python, um Methoden in einer freigegebenen C++ - Bibliothek aufzurufen. Ich habe ein Problem, indem ich ein numpliges 2D-Array in ein C++ - 2D-Array von Kurzschlüssen als Funktionseingabe umwandelt. Ich habe ein Spielzeugbeispiel erstellt, das das Problem aufweist. Fühlen Sie sich frei, es zu kompilieren und auszuprobieren! HierWandeln Sie ein 2D-Nummernfeld in C++ um.

ist der Python-Code (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) 

Hier ist die C++ Bibliothek (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);  
    } 
} 

die ich mit dem folgenden Befehl kompilieren:

Wenn ich die Python-Datei ausführen, erhalte ich den folgenden Fehler:

>> python soexample.py 
Traceback (most recent call last): 
    File "soexample.py", line 13, in <module> 
    cpplib.func_py(cppobj,array) 
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how to  convert parameter 2 

Wie korrigiere ich diesen unglücklichen TypeError richtig?

+1

glaube ich, C Kurz Ints 16 Bits sind. Der Standardwert numpy int ist typischerweise 32 Bit. Sie können versuchen, Ihr Array als 'array = np.array ([[1,2,3], [1,2,3]], dtype = np.uint16)' zu erstellen und zu sehen, was passiert. – Jaime

Antwort

4

Sie können ctypesc_short und POINTER verwenden, um mit der Zwischenkonversion zu helfen. Die folgende Funktion wandelt ein numpy Array in ein C-type 2darray um, das an eine C-Funktion übergeben werden kann, die short ** erwartet.

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 

Hinweis, modifizierte I func_pyCPPClass::func und 2 zusätzliche Parameter zu nehmen, die Breite und die Länge des gegebenen Arrays. Damit kann CPPClass::func alle Elemente des Arrays ausdrucken:

// ... 
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); 
} 

Mit dieser Hilfsfunktion definiert ist, sollte Folgendes jetzt arbeiten:

>>> 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

Danke! Das hat perfekt funktioniert. Ich habe eine andere ähnliche Frage, dass Sie mir hier helfen könnten: http://stackoverflow.com/questions/17138054/return-c-double-to-python – dillerj

Verwandte Themen