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 开发者_Go百科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!
Foo f;
initializeFoo(&f);
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,
Foo *f;
f = new Foo();
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.
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
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.
精彩评论