2011-10-13 173 views
0

我目前正在使用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'中没有这个类型。

问题是:有没有什么办法可以生成一个返回'j''jint'或'Ljvava_lang_String_2'给'jstring'的宏。请注意,无法使用字符串化,并且需要在第二个生成的方法名称中使用“ILjava_lang_String_2”而不是“II”。

谢谢!

回答

2

那么,您提供的链接几乎为您提供了所需的解决方案。试想一下:

#define CONCATENATE(arg1, arg2) CONCATENATE1(arg1, arg2) 
#define CONCATENATE1(arg1, arg2) CONCATENATE2(arg1, arg2) 
#define CONCATENATE2(arg1, arg2) arg1##arg2 

#define JNI_TRANSLATE_TYPE_jint I 
#define JNI_TRANSLATE_TYPE_jstring Ljava_lang_String_2 

#define JNI_TRANSLATE_TYPE(T) CONCATENATE(JNI_TRANSLATE_TYPE_, T) 

测试,在VS2010:

#define STRINGIZE(arg) STRINGIZE1(arg) 
#define STRINGIZE1(arg) STRINGIZE2(arg) 
#define STRINGIZE2(arg) #arg 

#pragma message("jint: " STRINGIZE(JNI_TRANSLATE_TYPE(jint))) 
#pragma message("jstring: " STRINGIZE(JNI_TRANSLATE_TYPE(jstring))) 

输出:

1> jint: I 
1> jstring: Ljava_lang_String_2 
+0

你是对的,我没有意识到我能够这样做。这不是处理定义内容,只是替换它,但在这种情况下,它可以正常工作。谢谢! – Charlie

0

您也可以考虑使用SWIG为您生成的JNI包装。它可以处理和隐藏所有用JNI包装对象的讨厌代码,以及许多其他语言映射。

相关问题