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

时间:2011-03-02 15:18:50

标签: java c++ pointers java-native-interface jna

免责声明:我几乎忽略了关于C ++的一切,所以我希望我不会在这里说愚蠢的事情,如果我有,请随时纠正我。

作为Java开发人员,当我想创建一个新对象时,我使用一个构造函数方法,它将在内存中分配这个对象并为它返回一个句柄,我将把这个句柄存储在一个变量中,我这样做就像这样。

Foo o = new Foo();

但是在C ++中,我已经理解,尽管事实上可以这样做

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

// ...

Foo f = createFoo();

我也可以自己定义一个句柄,然后在其上调用一个初始化程序,它将分配内存并绑定句柄,如下所示:

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

// ...

Foo f;
initializeFoo(&f);

所以我的问题是,当我们想在JNA中使用Java中的那些C ++方法时会发生什么?

假设我有以下C ++标题:

typedef struct Foo f;

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

由于我不知道Foo是什么,或者Foo结构包含什么,我只是想创建一个JNA PointerType来声明我的结构:

public class Foo extends PointerType{

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

使用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();
    }

右?

但我的问题是,如何使用initializeFoo函数???我想我必须创建一个指针并将其赋予函数,但是如何在JNA中创建非NULL指针?我尝试了以下代码,但结果是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
    }

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

Foo f;
initializeFoo(&f);
正如你所说,

initializeFoo()没有“为f分配内存并绑定句柄”。 Foo f;创建f并将其分配给内存。 initializeFoo()可以执行诸如为f的成员属性等分配值,以及创建另一个Foo对象并将其分配给f,但它不会按照您的说法执行操作。

另一方面,

Foo *f;
f = new Foo();

声明一个Foo指针。 new分配内存并创建一个Foo对象,并将内存位置分配给f(您可以将指针视为包含地址的整数)。

我认为您希望在进一步学习之前了解有关C ++和指针的更多信息。

答案 1 :(得分:1)

  

因为我对Foo是什么,或者Foo结构包含什么没有任何想法,我只是想创建一个JNA PointerType来声明我的结构

这使得无法为Foo分配内存,因为您必须知道需要分配多少内存。对于c结构,jna​​需要一个镜像结构的java类,或者如果你至少知道它的大小,你可以尝试使用带有一个大小参数的ctor的Memory类。

对于使用c ++特性(如继承)的c ++结构和类,这会失败,因为所需的内存和布局取决于编译器和启用的优化。