是否可以使用宏来处理定义的内容?
我目前正在使用 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在此链接中的回答 这可能吗迭代可变参数宏中的参数? 我现在可以使用预处理器验证我在宏中引入了多少参数并处理每个参数。
但从前面的例子来看,我无法实现我想要实现的目标。假设我在名为 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”。
谢谢!
I am currently working with JNI (Java Native Interface) to send data between Java and C++. After implementing a little of code I realized the code for each method was always similar. An example could be:
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);
}
Due to all the code has a similar structure, I decided generate a set of macros to generate automatically all this code. Thanks to Gregory Pakosz' answer in this link Is it possible to iterate over arguments in variadic macros? I am now able to verify using the preprocessor how many parameters I introduced in a macro and process every single param.
But from the previous example there is a thing I am unable to achive that I would like to. Suppose I have this method inside a macro called JNI_METHOD. I would like to do something like this:
#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);
In order to avoid having this question too long I didn't paste the declaration of SET_DECLARATION_PARAMS and SET_DECLARED_PARAMS but the first one will result in something like 'jint arg1' and the second in 'arg1' without the type.
The question is: is there any way to generate a macro returning 'I' for 'jint' or 'Ljava_lang_String_2' for 'jstring'. Note that the stringification cannot be used and this is needed to have 'ILjava_lang_String_2' instead of 'II' in the second generated method name.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,您提供的链接几乎为您提供了所需的解决方案。考虑一下:
在 VS2010 上测试:
输出:
Well, the link you provided pretty much gives you the solution you need. Consider this:
Test, on VS2010:
Output:
您还可以考虑使用 SWIG 为您生成 JNI 包装器。它可以处理和隐藏所有使用 JNI 包装对象的讨厌代码以及许多其他语言映射。
You might also consider using SWIG to generate the JNI wrappers for you. It can handle and hide all the nasty code for wrapping objects with JNI, as well as many other language mappings.