编辑:请参见这个更优雅的答案。
下面的机制基于一个C预处理器宏,我已经成功地在JNI层中实现了这个宏。
上述宏CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
将C ++异常转换为Java异常。
请用您自己的C++异常替换mypackage::Exception
。如果您没有在Java中定义相应的my.group.mypackage.Exception
,则将"my/group/mypackage/Exception"
替换为"java/lang/RuntimeException"
。
#define CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION \
\
catch (const mypackage::Exception& e) \
{ \
jclass jc = env->FindClass("my/group/mypackage/Exception"); \
if(jc) env->ThrowNew (jc, e.what()); \
\
} \
catch (const std::bad_alloc& e) \
{ \
\
jclass jc = env->FindClass("java/lang/OutOfMemoryError"); \
if(jc) env->ThrowNew (jc, e.what()); \
} \
catch (const std::ios_base::failure& e) \
{ \
\
jclass jc = env->FindClass("java/io/IOException"); \
if(jc) env->ThrowNew (jc, e.what()); \
} \
catch (const std::exception& e) \
{ \
\
jclass jc = env->FindClass("java/lang/Error"); \
if(jc) env->ThrowNew (jc, e.what()); \
} \
catch (...) \
{ \
\
jclass jc = env->FindClass("java/lang/Error"); \
if(jc) env->ThrowNew (jc, "unidentified exception"); \
}
使用上述宏定义的文件名为 Java_my_group_mypackage_example.cpp
:
JNIEXPORT jlong JNICALL Java_my_group_mypackage_example_function1
(JNIEnv *env, jobject object, jlong value)
{
try
{
return jlong(result);
}
CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
return 0;
}
JNIEXPORT jstring JNICALL Java_my_group_mypackage_example_function2
(JNIEnv *env, jobject object, jlong value)
{
try
{
jstring jstr = env->NewStringUTF("my result");
return jstr;
}
CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
return 0;
}
JNIEXPORT void JNICALL Java_my_group_mypackage_example_function3
(JNIEnv *env, jobject object, jlong value)
{
try
{
}
CATCH_CPP_EXCEPTION_AND_THROW_JAVA_EXCEPTION
}
仅供参考或好奇心,以下提供相应的Java代码(文件example.java
)。请注意,“my-DLL-name
”是上述C/C++代码编译为DLL(不带“.dll
”扩展名的“my-DLL-name
”)。这也可以使用Linux/Unix共享库*.so
。
package my.group.mypackage;
public class Example {
static {
System.loadLibrary("my-DLL-name");
}
public Example() {
}
private native int function1(int);
private native String function2(int);
private native void function3(int);
public void dosomething(int value) {
int result = function1(value);
String str = function2(value);
function3(value);
}
}
首先,使用 javac
或您喜欢的集成开发环境或maven从example.java
生成example.class
。其次,使用javah
从example.class
生成C/C++头文件Java_my_group_mypackage_example.h
。