我需要編寫一個自動生成將所有參數轉發給另一個(成員)函數的函數的宏。使用c預處理器自動生成函數轉發器
如果您需要知道爲什麼需要它,我需要簡化編寫JNI膠水。 我會省略其他原因,爲什麼我需要這樣做,我只是提到我不能使用boost(儘管我可能會刪除所需的部分並將其從boost轉換爲我自己的宏)。我還檢查了一些其他庫(jace等),但沒有找到任何符合我需要的東西。
總之,這裏的示例JNI功能:
class TestClass
{
void nativeTest(JNIEnv *, jobject, jint, jboolean)
{
...
}
static TestClass* getPeer(JNIEnv *, jobject obj)
{
...
}
}
JNIEXPORT void JNICALL Java_com_noname_media_TestClass_nativeTest(
JNIEnv *env, jobject obj, jint i, jboolean b
)
{
TestClass* peer = TestClass::getPeer(env, obj, i, b);
if(peer)
return peer->nativeTest(env, obj, i, b);
return;
}
現在,我想寫一些JNI_FUNCTION
宏,會自動生成所有Java_com_noname_media_TestClass_nativeTest。經過一番思考,我想我能做到這一點是這樣的:
#define JNI_FUNCTION(functionName, functionReturn, functionArgs) \
JNIEXPORT functionReturn JNICALL \
Java_com_noname_media_TestClass##functionName(**WTF**) \
{
TestClass* peer = TestClass::getPeer(**WTF**);
if(peer)
return peer->functionName(**WTF**);
return;
}
然後,使用JNI_FUNCTION
我可以做這樣的事情:
JNI_FUNCTION(nativeTest, void, (JNIEnv *, jobject, jint, jboolean));
的問題是,我不知道如何「破解」函數參數,因爲我需要爲列表functionArgs
中的每個條目添加自動編號的參數名稱。
其他陷阱:返回類型可以是某種類型或無效,但對於無效的情況下,我可能會單獨使用JNI_VOID_FUNCTION
以防萬一使用常規方式無法輕鬆完成。我所有的jni函數在functionArgs
列表中至少有兩個參數,例如它不能爲空列表()
。 我沒有使用functionArgs作爲包含多個參數一個參數,我確定這個方式,以及:
#define JNI_FUNCTION(functionName, functionReturn, ...)
無論工作......也許我需要某種宏觀的,讓我在某個位置提取一些宏,比如ARG_1(...)等,但到目前爲止,我無法將它全部包裝在我的大腦中如何去做。
PS。我記得在使用c-preprocessor時有一些非常酷的例子,在這裏有非常好的解釋,但是現在找不到它們,如果你有書籤,也許我需要的只是看看它們。
編輯: 基本上,關鍵是要自動編號名稱添加到每個參數,然後將它們作爲-是一個成員函數。我需要這樣做的原因是因爲除了預處理器之外,還有其他一些自動生成功能。總之,這個宏實際上將一組類似的宏(在ATL/WTL的東西等)中使用:
JNI_TABLE_BEGIN(ClassName)
JNI_FUNCTION(native1, void, (JNIEnv *, jobject, jint))
JNI_FUNCTION(native2, void, (JNIEnv *, jobject, jint))
JNI_FUNCTION(native3, jint, (JNIEnv *, jobject))
JNI_TABLE_END()
您確定這應該被標記爲C嗎? Java或C++中的JNI函數是什麼? –
哦,好的,喬納森,你是最酷的c預處理器樣本,我馬上認出你的名字:)我會檢查你的回覆,也許我會在那裏找到我需要的。是的,我的文章只有c/C++的東西,這裏沒有涉及java。 – Pavel
我的問題的意義在於代碼'class TestClass {...}'不能是C;它只能是C++。所以,你應該把你的問題標記爲C++。另一個標籤很好。在決定可以做什麼和不可以做什麼之前,您應該查看Boost預處理器代碼。 –