简体   繁体   English

C ++的out参数对象创建和JNA

[英]C++'s out parameter object creation and JNA

Disclaimer: I ignore pretty much everything about C++, so I hope I'm not saying stupid things here, if I am, please feel free to correct me. 免责声明:我几乎忽略了有关C ++的所有内容,所以我希望我在这里不要说愚蠢的话,如果我愿意,请随时纠正我。

As a Java developer, when I want to create a new object, I use a constructor method that will allocate this object in memory and return a handle on it for me, and I will store this handle in a variable, I do it like this. 作为Java开发人员,当我想创建一个新对象时,我使用了一个构造函数方法,该方法将在内存中分配该对象并为我返回一个句柄,并将该句柄存储在变量中,我这样做。

Foo o = new Foo();

But in C++, I've been given to understand, that despite the fact it is possible to do so 但是在C ++中,我已经明白,尽管事实上有可能这样做

Foo createFoo(){
    Foo f;
    f.doSomething();
    return f;
}

// ...

Foo f = createFoo();

I can also define a handle by myself, and then call a initializer on it that will allocate memory and bind the handle on it, like this: 我还可以自己定义一个句柄,然后在其上调用一个初始化程序,该方法将分配内存并在其上绑定该句柄,如下所示:

void initializeFoo(Foo **f){
    f.doSomething();
    return;
}

// ...

Foo f;
initializeFoo(&f);

So my question is, what happens when we want to use those C++ methods in Java, with JNA? 所以我的问题是,当我们想通过JNA在Java中使用这些C ++方法时会发生什么?

Let's suppose I have the following C++ header: 假设我有以下C ++标头:

typedef struct Foo f;

Foo createFoo();
void initializeFoo(Foo **f);

As I don't have any idea on what a Foo is, or what the Foo structure contains, I'm just going to create a JNA PointerType to declare my structure: 由于我对Foo是什么或Foo结构包含的内容一无所知,因此我将创建一个JNA PointerType来声明我的结构:

public class Foo extends PointerType{

    public Foo(Pointer address) {
        super(address);
    }
    public Foo() {
        super();
    }
}

Using the createFoo method should be pretty easy as well: 使用createFoo方法也应该很容易:

public class TestFoo{
    static{
        System.loadLibrary("foolib");
    }

    public static void main(String[] args){
        FooLib lib = (FooLib)Native.loadLibrary("foolib", FooLib.class);

        Foo f = lib.createFoo();
    }

Right? 对?

But my question is, how can I use the initializeFoo function??? 但是我的问题是,如何使用initializeFoo函数??? I suppose I would have to create a Pointer and give it to the function, but how do I create a non NULL pointer in JNA? 我想我必须创建一个Pointer并将其提供给函数,但是如何在JNA中创建一个非NULL指针呢? I tried the following code, but it results in an EXCEPTION_ACCESS_VIOLATION. 我尝试了以下代码,但结果为EXCEPTION_ACCESS_VIOLATION。

public class TestFoo{
    static{
        System.loadLibrary("foolib");
    }

    public static void main(String[] args){
        FooLib lib = (FooLib)Native.loadLibrary("foolib", FooLib.class);

        Foo f = new Foo();
        lib.initializeFoo(f); // EXCEPTION_ACCESS_VIOLATION
        lib.initializeFoo(f.getPointer()); // EXCEPTION_ACCESS_VIOLATION
    }

Any idea? 任何想法?

Thanks! 谢谢!

Foo f;
initializeFoo(&f);

initializeFoo() does not "allocate memory and bind the handle" for f, as you say. 如您所说, initializeFoo()不会为f“分配内存并绑定句柄”。 Foo f; creates f and allocates it in memory. 创建f并将其分配到内存中。 initializeFoo() could do something like assign values to f's member properties, and the like, as well as create another Foo object and assign it to f, but it does not do what you say. initializeFoo()可以执行类似的操作,例如,将值分配给f的成员属性等,以及创建另一个Foo对象并将其分配给f,但它不会执行您所说的。

On the other hand, 另一方面,

Foo *f;
f = new Foo();

declares a Foo pointer. 声明一个Foo指针。 new allocates memory and creates a Foo object, and assigns the memory location to f (you can think of a pointer as a integer containing an address). new分配内存并创建Foo对象,并将内存位置分配给f(您可以将指针视为包含地址的整数)。

I think you want to learn more about C++ and pointers before you go any further. 我认为您想进一步了解C ++和指针。

As I don't have any idea on what a Foo is, or what the Foo structure contains, I'm just going to create a JNA PointerType to declare my structure 由于我对Foo是什么或Foo结构包含的内容一无所知,因此我将创建一个JNA PointerType来声明我的结构

This makes it impossible to allocate memory for Foo, as you have to know how much memory you need to allocate. 这使得不可能为Foo分配内存,因为您必须知道需要分配多少内存。 For c structures jna needs a java class mirroring the structure or if you at least know its size you can try to use the Memory class which has a ctor taking a size argument. 对于c结构,jna​​需要一个镜像该结构的java类,或者如果您至少知道其大小,则可以尝试使用Memory类,该类的ctor带有size参数。

For c++ structures and classes using c++ features like inheritance this fails since the required memory and layout depends on the compiler and enabled optimisations. 对于使用c ++功能(例如继承)的c ++结构和类,由于所需的内存和布局取决于编译器和启用的优化,因此此操作失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM