簡體   English   中英

如何在JNA中使用C ++對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM