2011-10-13 120 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包裝對象的討厭代碼,以及許多其他語言映射。

相關問題