我使用 SWIG 为 Irrlicht C/C++ 3D 引擎生成了一些本机 JNI 函数接口,我得到了一堆 java 代理类和一个中间 c/c++ 文件,它们实现了 java 本机函数来粘合 java 代理类和 Irrlicht C/ C++ 3d 引擎。
所有 java 代理类都在包 net.sf.jirr 中生成。并且生成的 java 原生方法定义在 net.sf.jirr.JirrJNI 类中。
由于 SWIG 生成的 c/c++ jni 函数的名称不符合默认的 android jni 函数调用约定,我需要手动将这些 java 本机方法注册到相应的 C/C++ jni 函数中。
即以生成的java native方法net.sf.jirr.JirrJNI.SColor_setRed为例: 生成的java native方法定义为:
public final static native void SColor_setRed(long jarg1, SColor jarg1_, long jarg2);
生成的c/c++ jni函数定义为:
SWIGEXPORT void JNICALL Java_net_sf_jirr_JirrJNI_SColor_1setRed(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jlong jarg2)
由于c/c++ jni函数不符合android c/c++ jni函数调用约定(在这种情况下生成的c/c++ jni函数名称应该是Java_net_sf_jirr_JirrJNI_SColor_setRed,如果它需要在JNI_OnLoad函数中不注册本机函数的情况下调用.)
因此,我正在尝试手动注册本机方法,例如:
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
......
if (!registerNativeMethods(env, JNI_REG_CLASS, (JNINativeMethod*)JNI_METHODS, JNI_METHODS_COUNT)) {
return -1;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;
return result;
}
其中 JNI_REG_CLASS、JNI_METHODS、JNI_METHODS_COUNT 定义为:
#define SET_A_JNI_METHOD(name, signature, func_ptr) \
{ (char*)#name, (char*)signature, (void*)func_ptr }
const char* JNI_REG_CLASS = "net/sf/jirr/JirrJNI";
JNINativeMethod JNI_METHODS[] = { SET_A_JNI_METHOD(SColor_setRed, "(JLnet/sf/jirr/SColor;J)V", Java_net_sf_jirr_JirrJNI_SColor_1setRed), ......};
int JNI_METHODS_COUNT = sizeof(JNI_METHODS) / sizeof(JNI_METHODS[0]);
因此,我需要解析 net.sf.jirr.JirrJNI 类并为所有 Java 本地方法生成一堆 SET_A_JNI_METHOD(......) 宏。
在这个 SET_A_JNI_METHOD 宏中,名称部分只是 java 原生函数名称;签名部分符合java jni方法签名标准(在官方java jni JNINativeMethod参考中有解释);func_ptr部分是添加Java_$(PackageName)_作为前缀,在java原生方法名的每一部分(不包括类名部分)后面加上一些索引号(这里用“_”隔开)。IE:
Java native method: IFileSystem_getFileDir
name part: IFileSystem_getFileDir;
func_ptr part: Java_net_sf_jirr_JirrJNI_IFileSystem_1getFileDir;
Java native method: IFileSystem_addFolderFileArchive__SWIG_0
name part: IFileSystem_addFolderFileArchive__SWIG_0;
func_ptr part: Java_net_sf_jirr_JirrJNI_IFileSystem_1addFolderFileArchive_1_1SWIG_10
有关如何使用 Python 正则表达式完成此操作的任何提示?