Java C++';s out参数对象创建和JNA 免责声明:我忽略了C++的所有内容,所以我希望我在这里不要说傻话,如果我是,请随时纠正我。

Java C++';s out参数对象创建和JNA 免责声明:我忽略了C++的所有内容,所以我希望我在这里不要说傻话,如果我是,请随时纠正我。,java,c++,pointers,java-native-interface,jna,Java,C++,Pointers,Java Native Interface,Jna,作为一名Java开发人员,当我想要创建一个新对象时,我使用一个构造函数方法,它将在内存中分配这个对象并为我返回一个句柄,我将这个句柄存储在一个变量中,我这样做 Foo o = new Foo(); 但是在C++中,我已经理解了,尽管事实上可以这样做< /P> Foo createFoo(){ Foo f; f.doSomething(); return f; } // ... Foo f = createFoo(); 我也可以自己定义一个句柄,然后调用它的初始值设

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

Foo o = new Foo();
<>但是在C++中,我已经理解了,尽管事实上可以这样做< /P>
Foo createFoo(){
    Foo f;
    f.doSomething();
    return f;
}

// ...

Foo f = createFoo();
我也可以自己定义一个句柄,然后调用它的初始值设定项,它将分配内存并绑定句柄,如下所示:

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

// ...

Foo f;
initializeFoo(&f);
<> P>这是问题,当我们想在java中使用C++的方法时,会发生什么?

让我假设我有以下C++头:< /P>

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();
    }
对吧?

但我的问题是,如何使用Initializefo函数???我想我必须创建一个指针并将其交给函数,但是如何在JNA中创建一个非空指针呢?我尝试了以下代码,但它导致了异常访问冲突

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
    }
有什么想法吗

谢谢

Foo f;
initializeFoo(&f);
initializefo()
没有像您所说的那样为f“分配内存并绑定句柄”<代码>foof创建f并在内存中分配它
initializefo()
可以做一些类似于为f的成员属性赋值之类的事情,还可以创建另一个Foo对象并将其赋值给f,但它不按照您所说的做

另一方面,

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

我想在继续学习之前,你还想了解更多关于C++和指针的知识。

initializefo()
没有像您所说的那样为f“分配内存并绑定句柄”<代码>foof创建f并在内存中分配它
initializefo()
可以做一些类似于为f的成员属性赋值之类的事情,还可以创建另一个Foo对象并将其赋值给f,但它不按照您所说的做

另一方面,

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

我想在继续学习之前,你还想了解更多关于C++和指针的知识。 因为我不知道什么是Foo,或者Foo结构包含什么,所以我将创建一个JNA指针类型来声明我的结构

这使得为Foo分配内存变得不可能,因为您必须知道需要分配多少内存。对于c结构,jna需要一个java类来镜像该结构,或者如果您至少知道它的大小,您可以尝试使用内存类,该类有一个接受大小参数的ctor

<>对于C++结构和类,使用C++继承的特征,失败了,因为所需的内存和布局依赖于编译器和启用的优化。 因为我不知道什么是Foo,或者Foo结构包含什么,所以我将创建一个JNA指针类型来声明我的结构

这使得为Foo分配内存变得不可能,因为您必须知道需要分配多少内存。对于c结构,jna需要一个java类来镜像该结构,或者如果您至少知道它的大小,您可以尝试使用内存类,该类有一个接受大小参数的ctor


<>对于C++结构和类,使用C++继承的特征,因为需要的内存和布局取决于编译器和启用的优化。失败了。你的C++函数和方法是否被正确地导出?@ AJG85:是的,它们是API的一部分。你的C++函数和方法是否正确导出?@ AJG85:是的,它们是API的一部分。@josefx:因此,如果我不知道Foo结构,我就无法将我的
initializefo(Foo**f)
方法用于JNA?@josefx:我会尝试为此结构分配内存,但我无法知道它的大小,它是在专有API中定义的。我想我可以通过将其定义为指针来避免这个问题。@nathanb如果它是在专有api中定义的,那么这个api要么提供一个返回指针的方法,要么有一个定义Foo结构的头文件。@nathanb您可以尝试com.sun.jna.ptr.PointerByReference并调用getValue()获取结果指针。@nathanb您是否检查了它的文档,其中显示了指针引用的示例。您还可以传递具有非空sp_会话值的sp_会话的单元素数组,以获得相同的结果。@josefx:因此,如果我不知道Foo结构,我无法将我的
initializefo(Foo**f)
方法用于JNA?@josefx:我会尝试为此结构分配内存,但我无法知道其大小,它是在专有API中定义的。我想我可以通过将其定义为指针来避免这个问题。@nathanb如果它是在专有api中定义的,那么这个api要么提供一个返回指针的方法,要么有一个定义Foo结构的头文件。@nathanb您可以尝试com.sun.jna.ptr.PointerByReference并调用getValue()获取结果指针。@nathanb您是否检查了它的文档,其中显示了指针引用的示例。此外,您还可以传递具有非空sp_会话值的sp_会话的单个元素数组,以获得相同的结果。