Open Vasniktel opened 4 years ago
You'll need to provide more information about the API you're trying to map if you'd like specific help about that.
I'm just experimenting with the library right now. I have the following class on the Java side.
package test;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
@Platform(include="../test.hpp")
@Namespace("test")
public class Lib {
static { Loader.load(); }
// Should return a pointer to the allocated array
// IntPointer should take ownership of the returned data
public static native IntPointer bar();
public static void main(String[] args) {
bar();
}
}
Which uses this C++ function
namespace test {
int* bar() {
return new int[4]{1, 2, 3, 4};
}
}
As indicated in the comments, IntPointer
should take ownership of the array, returned from bar
function.
As for NullPointerException
, I'm guessing that method should be non-static
to use @ArrayAllocator
or @Allocator
.
That's just a raw pointer, with no clue as to how to deallocate it. You can't expect any framework to be able to do anything about it automatically. First, you'll need to provide some function to deallocate it, something like this:
namespace test {
int* bar() {
return new int[4]{1, 2, 3, 4};
}
void foo(int* bar) {
delete[] bar;
}
}
Then we can use that function...
Thanks for the reply!
First, you'll need to provide some function to deallocate it
That is clear. The question that I'm struggling to answer, is how to make IntPointer
result aware of it.
Is there any way to do it?
What you're looking for is probably a custom deallocator. The typical pattern looks like this: https://github.com/bytedeco/javacpp/wiki/Mapping-Recipes#writing-additional-code-in-a-helper-class Applying that to this case, we could have something like this:
public static native MyIntPointer bar();
public static native void foo(MyIntPointer bar);
public class MyIntPointer extends IntPointer {
protected static class MyDeallocator extends MyIntPointer implements Deallocator {
MyDeallocator(MyIntPointer p) { super(p); }
@Override public void deallocate() { foo(this); }
}
public MyIntPointer(Pointer p) { super(p); }
public static MyIntPointer create() {
MyIntPointer p = bar();
if (p != null) {
p.deallocator(new MyDeallocator(p));
}
return p;
}
}
Obviously this could be enhanced somehow using annotations...
Hey, @saudet, thanks for the reply. This solves the problem!
I have another question though. I've noticed that javacpp
calls javac
during execution even though I need to only generate .cpp
files in my application. Is there any way to disable it?
Sure, there's a -nocompile
command line option and a compile
flag for Maven we can set to false:
http://bytedeco.org/javacpp/apidocs/org/bytedeco/javacpp/tools/BuildMojo.html#compile
-nocompile
only disables compilation of .cpp
files for me. I wanted to disable compilation of .java
files as well. I just want javacpp
to generate c++ sources. Is this possible?
No, JavaCPP needs some Java code to work. Your question doesn't make sense.
Yep, my mistake, sorry for the confusion :)
If you're talking about what happens when you give it a .java
file, that's just for convenience. Don't give it .java
files, just give it some class names, and it will use those.
Hi everyone. The issue is the following. I have to transfer ownership of an allocated data (an array) from C++ to Java. How would I do that?
As a side note: I've tried to work something out with
@ArrayAllocator
annotation but haven't quite understood the idea of how it works. I got a couple ofNullPointerExceptions
during my experiments that look like this:The question is how those annotations work and whether this exception is an intended behaviour?