开发者

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++ :P


You 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜