【发布时间】:2011-10-13 23:15:45
【问题描述】:
我目前正在使用 JNI(Java 本机接口)在 Java 和 C++ 之间发送数据。在实现了一些代码之后,我意识到每种方法的代码总是相似的。一个例子可能是:
JNIEXPORT void JNICALL Java_com_trial_jni_Receiver_setData__II(JNIEnv * env, jobject thiz, jint nativeObject, jint value)
{
reinterpret_cast<Receiver *>(nativeObject)->setData(value);
}
JNIEXPORT void JNICALL Java_com_trial_jni_Receiver_setData__ILjava_lang_String_2(JNIEnv *env, jobject thiz, jint nativeObject, jstring value)
{
reinterpret_cast<Receiver *>(nativeObject)->setData(value);
}
由于所有代码都有类似的结构,我决定生成一组宏来自动生成所有这些代码。感谢 Gregory Pakosz 在此链接 Is it possible to iterate over arguments in variadic macros? 中的回答,我现在能够使用预处理器验证我在宏中引入了多少参数并处理每个参数。
但是从前面的示例中,有一件我无法实现的事情我想要。假设我在一个名为 JNI_METHOD 的宏中有这个方法。我想做这样的事情:
#define JNI_METHOD(package,clazz,method,...) \
JNIEXPORT void JNICALL Java_ ##package## _ ##clazz## _ ##method##__II(JNIEnv * env, jobject thiz, jint nativeObject, SET_DECLARATION_PARAMS(__VA_ARGS__ )) \
{ \
reinterpret_cast<clazz *>(nativeObject)->method(SET_DECLARED_PARAMS(__VA_ARGS__)); \
}
JNI_METHOD(com_trial_jni,Receiver,setData,jint);
JNI_METHOD(com_trial_jni,Receiver,setData,jstring);
为了避免这个问题太长,我没有粘贴 SET_DECLARATION_PARAMS 和 SET_DECLARED_PARAMS 的声明,但是第一个会导致类似于“jint arg1”的结果,而第二个会在没有类型的情况下出现在“arg1”中。
问题是:有什么方法可以生成一个宏,为“jint”返回“I”或为“jstring”返回“Ljava_lang_String_2”。请注意,不能使用字符串化,这需要在第二个生成的方法名称中包含“ILjava_lang_String_2”而不是“II”。
谢谢!
【问题讨论】:
标签: c++ c java-native-interface c-preprocessor