Ich versuche auf eine C++ - Bibliothek von Java mit JNA zuzugreifen. Um dies zu tun, habe ich einen dünnen Wrapper um die C++ - Methoden geschrieben, die ich benötige. Das Umbrechen des C++ - Objekts, die Übergabe an Java und zurück an C++ führt jedoch beim Zugriff auf das Objekt in C++ zu einem ungültigen Speicherzugriff. Hinweise dazu, warum dies geschieht, sind sehr hilfreich.Wie arbeite ich mit C++ - Objekten in JNA
newencoder.h
Class Encoder {
public:
Encoder();
~Encoder();
template<class Type>
bool originalEncode(Type* input);
}
encoder_wrapper.h
typedef void* EncoderWrap;
extern "C" {
EncoderWrap newEncoder();
const char* encode(EncoderWrap vcEncoder);
}
encoder_wrapper.cpp
#include "encoder_wrapper.h"
#include "newencoder.h"
EncoderWrap newEncoder() {
return reinterpret_cast<void*>(new Encoder());
}
const char* encode(EncoderWrap encoderObj) {
std::string input;
(reinterpret_cast<Encoder*>(encoderObj))->originalEncode(&input); //This is where the invalid memory access occurs. Commenting this line and returning a placeholder string does not throw any error.
return input.c_str();
}
JNA
private static class Encoder {
public static native Pointer newEncoder();
public static native String encode(Pointer encoderObj);
static {
Native.setProtected(true);
Native.register("encoderlib");
}
}
//Code that calls the native methods
Pointer encoderObj = Encoder.newEncoder(); //Does not fail
String result = Encoder.encode(encoderObj); //Results in Invalid Memory access
ich Aufruf versucht, die encode()
Methode aus dem C++ Methode newEncoder()
und das funktioniert wie erwartet. Dieser Speicherfehler tritt nur auf, wenn ich das Encoderobjekt, das in Java als void * übergeben wurde, an die C++ - Methode enocode()
zurückgebe.
Sie _definitely_ können nicht 'std :: string' zurückgeben, müssen Sie einen zugewiesenen Speicherblock zurückgeben, der eine C-Zeichenfolge enthält (nominal std :: string.c_str()), die garantiert erst nach JNA freigegeben wird hat die Möglichkeit, basierend auf seinen Inhalten eine Java-Zeichenfolge zu erstellen. – technomage
Ich würde empfehlen, die Objektcodierung für das Objekt selbst zu speichern (selbst wenn es bei jedem Aufruf von 'encode' neu generiert wird), damit der Speicher nicht freigegeben wird, und dann einen Zeiger auf den C-Zeichenfolgenpuffer der Zeichenfolge zurückgibt. – technomage