2016-08-03 24 views
0

Ich habe eine C++ Funktion foo(unsigned char*& ptr) , die einen Puffer erstellt und füllt es mit binären Daten und setzt ptr, um es zu zeigen. Ich brauche den Inhalt des Puffers aus Java.SWIG/Java erhalten Puffer von unbekannter Größe von C++

Um zu klären, kann der C++ Code wie folgt verwendet werden:

unsigned char* ptr; 
foo(ptr); 
//now ptr points to a buffer, do what you want, eg 
x=ptr[1]; 

Mit arrays_java.i wird nicht funktionieren, weil SWIG die Array-Größe im Voraus wissen muss. Ich versuchte auch die eingebaute typemap NIOBUFFER für unsigned char*, die für unsigned char*& geändert wurde, aber das stellte Probleme mit dem erzeugten C++ - Wrappercode dar, in dem die JVM abstürzte, wenn sie versuchte, sie zu benutzen. Ich glaube auch nicht mit carrays.i wie in this answer funktioniert entweder, weil der Parameter unsigned char*& ist, nicht nur unsigned char*, aber ich habe dies noch nicht versucht. (EDIT mit %array_functions (int * Iarr) für eine Testfunktion

void test(int*& ia) 
{ 
ia[0]=1; 
... 
} 

Ergebnisse in einer JVM Absturz mit EXCEPTION_ACCESS_VIOLATION wie mit dem NIOBUFFER typemap geschah)

Gibt es eine Möglichkeit die Größe des Puffers von der C++/JNI-Wrapper zu bekommen Code und dann ein Java-Array bekannter Größe aus dem JNI-Code erstellen, so dass ich arrays_java.i nutzen kann?

Gibt es eine Möglichkeit, NIOBUFFER zu verwenden, möglicherweise mit Änderungen an seiner typemap und/oder dem generierten C++ - Wrapper?

Gibt es eine Möglichkeit, einige type*& als type* zu behandeln, so dass ich verwenden kann?

Da sowohl die NIOBUFFER typemap und array_functions die JVM abgestürzt ist, habe ich das Gefühl, dass die Wurzel meines Problems ist die type*& Parameter und dass eine Möglichkeit, dies zu lösen, wird eine dieser beiden Optionen zu ermöglichen. Wie mache ich das?

+0

Wie würden Sie den Puffer verwenden, wenn Ihr Hauptprogramm in C war und Sie JNI nicht verwendet haben, ohne die Größe zu kennen? – immibis

+0

Es gibt keine Möglichkeit, ein Java-Array zu erstellen, ohne die Größe des Arrays zu kennen. – immibis

+0

Ich sagte ausdrücklich, ich benutze SWIG, die JNI-Code generiert und dass eine Möglichkeit, die ich in Betracht ziehe, ist, diesen Code zu ändern, so dass es tut, was ich will. Dies könnte beinhalten, die C++ - Puffergröße zu erhalten und das von Java übergebene Array durch ein anderes mit geeigneter Größe zu ersetzen und dieses an Java zurückzugeben. Und natürlich interessiere ich mich für einfachere Ansätze. – BenK

Antwort

0

Ich habe eine Lösung gefunden. Unter der Annahme, die gleiche Funktion foo in meiner Frage:

  1. Schreiben Sie eine Funktion, sagen bar, die einen lokalen Zeiger erzeugt, geht es in foo, und gibt es zurück. In diesem Fall würde bar

    sein

    unsigned char* bar() { unsigned char* ptr; foo(ptr); return ptr; }

  2. in SWIG: Verwendung %array_classes, dh array_class(unsigned char, ShortArray)

  3. eine Instanz der Klasse erstellen Array über den Zeiger von bar durch frompointer Verwendung zurückgegeben. ShortArray sa = ShortArray.frompointer(example.bar())

Dies umgeht die Kopfschmerzen SWIG des Erhaltens mit type*& als Argin zu arbeiten/out, da Sie jetzt mit normalen Zeigern und Arrays zu tun, die SWIG just fine "out of the box" behandelt. Es ermöglicht auch der Java-Seite, einen Puffer beliebiger Größe zu erhalten und bietet auch mehr Java-ähnliche Syntax.

+0

Wenn '' foo' 'den Zeiger 'ptr' nicht auf einen Puffer zeigt, der entweder statisch ist oder ordnungsgemäß entsorgt wird, wenn Ihre Bibliothek beendet wird, verlieren Sie Speicher. Ich habe Ihr Problem 1000 Mal in Python gelöst, wenn Sie diese Lösung sehen möchten, kann ich Ihnen diese geben. –

+0

Nun, die Java-Seite hat in 'array_classes.i' die Funktion' delete'. Wird das Speicherleck verhindern? – BenK

+0

Es gibt fast ein komplettes Beispiel dafür, was Sie im SWIG-Handbuch im Java-Abschnitt zu tun versuchen. –