2011-10-13 2 views
0

현재 JNI (Java Native Interface)로 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라는 매크로 안에 있다고 가정합니다. 나는 이런 식으로 뭔가를 싶습니다

긴 내가 SET_DECLARATION_PARAMS 및 SET_DECLARED_PARAMS하지만 첫 번째는 'jint를의 ARG1'과 같이 발생합니다의 선언을 붙여하지 않았다 너무이 문제를 피하기 위해서는
#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); 

및 유형이없는 'arg1'의 두 번째

질문 : 'jint'에 대해 'I'또는 'jstring'에 대해 'Ljava_lang_String_2'를 반환하는 매크로를 생성하는 방법이 있습니까? 문자열 화는 사용할 수 없으며 두 번째 생성 된 메소드 이름에 'II'대신 'ILjava_lang_String_2'가 필요합니다.

감사합니다.

답변

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

또한 당신을위한 JNI 래퍼를 생성하는 SWIG를 사용하는 것이 좋습니다. JNI로 객체를 래핑하는 모든 불쾌한 코드와 많은 다른 언어 매핑을 처리하고 숨길 수 있습니다.

관련 문제