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