C++的out参数对象创建和JNA
免责声明:我几乎忽略了有关 C++ 的所有内容,因此我希望我没有在这里说愚蠢的话,如果是的话,请随时纠正我。
作为一名 Java 开发人员,当我想要创建一个新对象,我使用一个构造函数方法,该方法将在内存中分配该对象并为我返回它的句柄,我将这个句柄存储在一个变量中,我这样做。
Foo o = new Foo();
但在 C++ 中,我已经明白,尽管事实上可以这样做
Foo createFoo(){
Foo f;
f.doSomething();
return f;
}
// ...
Foo f = createFoo();
,但我也可以自己定义一个句柄,然后在其上调用一个初始化程序,该初始化程序将分配内存并绑定其上的句柄,例如this:
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
}
有什么想法吗?
谢谢!
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.
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.
Foo o = new Foo();
But in C++, I've been given to understand, that despite the fact it is possible to do so
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?
Let's suppose I have the following C++ header:
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:
public class Foo extends PointerType{
public Foo(Pointer address) {
super(address);
}
public Foo() {
super();
}
}
Using the createFoo method should be pretty easy as well:
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??? 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? I tried the following code, but it results in an 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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您所说,
initializeFoo()
不会为 f“分配内存并绑定句柄”。Foo f;
创建 f 并将其分配到内存中。initializeFoo()
可以执行诸如为 f 的成员属性赋值等操作,以及创建另一个 Foo 对象并将其分配给 f,但它不会执行您所说的操作。另一方面,
声明一个 Foo 指针。
new
分配内存并创建一个 Foo 对象,并将内存位置分配给 f(您可以将指针视为包含地址的整数)。我认为在继续之前您想了解更多有关 C++ 和指针的知识。
initializeFoo()
does not "allocate memory and bind the handle" for f, as you say.Foo f;
creates f and allocates it in memory.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.On the other hand,
declares a Foo pointer.
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).I think you want to learn more about C++ and pointers before you go any further.
这使得不可能为 Foo 分配内存,你必须知道您需要分配多少内存。对于 c 结构,jna 需要一个镜像结构的 java 类,或者如果您至少知道它的大小,您可以尝试使用 Memory 类,它有一个带有大小参数的 ctor。
对于使用继承等 C++ 功能的 C++ 结构和类,此操作会失败,因为所需的内存和布局取决于编译器和启用的优化。
This makes it impossible to allocate memory for Foo, as you have to know how much memory you need to allocate. 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.
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.