Use a C++ function in Java
I have a C++ project with some .cpp and .h files. One of these .cpp has a function with this signature:
int** verts(int L, int W, int l, int w)
I'd like to use this function in a Java project. Yes, I could rewrite it in Java, but it's a very very articulated function. It would be great calling this function (and obtain a matrix of integers) from Java.
An开发者_开发技巧y idea?
Please consider that I'm a Java programmer, I'm very noob in C++ :PYou can write a library which contains this function, and wraps it with
a JNI wrapper, but it's not trivial. The most important question is
what the int**
really represent, and how they are managed: whether and
how you have to delete them, and how you want to represent them in Java.
Just guessing, I suspect that the pointer points to an array of int*
,
each of which points to an array of int
; this is a common
representation for a two dimensional array in C (but not what we'd
normally use in C++). As for whether and how to delete them, this
should be documented by the library which defines verts
. Given that,
you'll first have to declare the function as native in a Java class:
class Verts
{
static {
System.loadLibrary( "<i>libraryName</i>" );
}
private static Integer[] nativeVerts( int L, int W, int l, int w );
public Integer[][] verts( int L, int W, int l, int w )
{
Integer[] tmp = nativeVerts( L, W, l, w );
// reshape tmp...
return reshapedData;
}
}
(I've preferred to return a flattened, single dimensional array, rather
than an Integer[][]
. It will make the C++ much simpler.)
what you'll have to do is write a function along the following lines:
#include "jni.h"
extern "C" JNIEXPORT jIntArray JNICALL Java_Verts_nativeVerts(
JNIEnv* env,
jclass,
jint L,
jint W,
jint l,
jint w)
{
int** results = verts( L, W, l, w );
std::vector<int> tmp;
// Fill tmp with the flattened results.
// Then do whatever you have to do to clean up the int**.
jintArray jResults = env->newIntArray( tmp.size() );
env->SetIntArrayRegion( jResults, 0, tmp.size(), &tmp[0] );
return jResults;
}
Except that the above also needs considerably more error checking.
Finally, compile and link the above into a dll with the name you gave to
the System.loadLibrary()
function on the Java side. And make sure
your environment is set up so that Java can find the dll (either through
$LD_LIBRARY_PATH (Unix) or %path% (Windows), or by passing the path by
means of -Djava.library.path=...
on the Java command line).
You won't be able to use that function directly (or if you do, you'll have a memory leak, since Java can't know how to free the memory allocated and returned by verts
). You should be able to write a simple wrapper that follows the JNI rules though.
When calling across languages, you really need to use caller-provided buffers. For this function, your wrapper will need to copy the results to the caller-provided buffer, and then use the appropriate C++ function to free the memory returned by verts
.
精彩评论