我有几个JNI函数必须在同一个c ++对象上工作。我想将该对象保存在调用JNI函数的java对象中,但似乎Java无法存储稍后要访问的函数的指针。
好的,我意识到我在解释自己的工作非常糟糕,所以这里有一个例子:
void clear_numbers(JNIEnv *env, jobject me) {
me.myCppVector.clear();
}
void set_number(JNIEnv *env, jobject me, jint index, jint num) {
me.myCppVector[index]=num;
}
jint get_number(JNIEnv *env, jobject me, jint index) {
returnme.myCppVector[index];
}
我的问题是创建一个jobject.myCppVector,以便我可以在不同的函数调用中使用它。
我希望有人理解我的谣言
答案 0 :(得分:6)
我认为实现它的标准方法是在java中使用long来存储指针,这样你的java代码就可以在32位和64位系统上运行。显然,您需要为每个平台编译不同的C ++ .so / .dll。
因此,使用一个方法的C ++类的简单java包装器将类似于:
class JavaClass
{
private long native_ptr = 0;
private native long createNativeInstance( params );
private native String nativeMethod( params );
private native void destroyNativeInstance( long p_native_ptr );
public JavaClass( params )
{
this.native_ptr = createNativeInstance( params );
}
public String javaMethod( params )
{
nativeMethod( this.native_ptr, params );
}
public void finalize()
{
destroyNativeInstance( this.native_ptr );
}
}
你的C ++包装器代码看起来像这样。 (我已将C ++类命名为CppClass
)
JNIEXPORT jlong JNICALL Java_JavaClass_createNativeInstance
( JNIEnv* p_jenv
, jobject p_jthis
, params )
{
// Convert params from Java types to C++ types if required
return (jlong) new CppClass( converted_params );
}
JNIEXPORT void JNICALL Java_JavaClass_destroyNativeInstance
( JNIEnv* p_jenv
, jobject p_jthis
, jlong p_native_ptr )
{
if( p_native_ptr )
delete (CppClass*)p_native_ptr;
}
JNIEXPORT jstring JNICALL Java_JavaClass_nativeMethod
( JNIEnv* p_jenv
, jobject p_jthis
, jlong p_native_ptr
, params
)
{
// Convert params from Java types to C++ types if required
std::string cpp_result = ((CppClass*)p_native_ptr)->cppMethod( converted_params );
jstring java_result = p_jenv->NewStringUTF( cppResult.c_str() );
return java_result;
// NOTE: std::string destructor will free cpp_result memory
}