[英]How to work with C++ objects in JNA
我正在嘗試使用JNA從Java訪問C ++庫。 為此,我圍繞所需的C ++方法編寫了一個瘦包裝。 但是,包裝C ++對象,傳遞給Java並返回給C ++會導致在訪問C ++對象時訪問無效內存。 關於為什么發生這種情況的任何指示都將非常有幫助。
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
我嘗試從C ++方法newEncoder()
內調用encode()
方法,該方法按預期工作。 僅當我在Java中收到轉換為void *的編碼器對象並將其傳遞回C ++方法enocode()
時,才會發生此內存錯誤。
正如Vybz所暗示的那樣,您的問題是將C ++與JNA混合在一起。 JNA不了解C ++結構,因此需要純C語言。
換句話說,您不能假定Java字符串與std :: string相同。 您不能在界面中使用std :: string。
很抱歉在這里發表評論,我沒有足夠的代表來正確發表評論部分。
我在Java JNA方面沒有太多經驗,但是在C ++世界中
extern "C" {}
用於使C ++代碼具有C鏈接。 在encoder_wrapper.h中,您使用的是std :: string,它是純c ++構造。 您是否嘗試過刪除外部字符“ C”?
我通過將void *封閉在結構中並將結構返回給JNA來解決了這個問題。 每次調用newEncoder
,都會創建一個結構實例,該實例將具有一個鑄造為void *的新Encoder對象作為成員。
每次將struct對象傳遞給encode
函數。 該方法又將void *強制轉換回該對象,並調用originalEncode
方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.