I need to write a macro that auto-generates a function that forwards all the arguments to another (member) function.
I need in to simplify writing JNI glue in case if you need to know why I need it. I'll omit other reason why I need it done this way, I simply mention that I cannot use boost (although, I may rip off needed pieces and translate from boost to my own macros); I also checked some other libs (jace etc), but didn't find anything that would fit my needs.
In short, here's example of a JNI function:
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;
}
Now, I want to write some JNI_FUNCTION
macro that would auto-generate all that Java_com_noname_media_TestClass_nativeTest. After some thought, I think I can do it something like this:
#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;
}
Then, to use the JNI_FUNCTION
I could do something like this:
JNI_FUNCTION(nativeTest, void, (JNIEnv *, jobject, jint, jboolean));
The problem is that I don't know how to "crack" the function parameters because I need to add auto-numbered argument names for each entry in the list of functionArgs
.
Other gotchas: return type can be some type or void, but for void case I may have separate JNI_VOID_FUNCTION
in case it cannot be done easily using regular way. All jni functions in my case will always have at least two args in the list of functionArgs
, e.g. it cannot be empty list ()
.
I don't have to use functionArgs as a single argument that contains multiple arguments, I'm ok with this way as well:
#define JNI_FUNCTION(functionName, functionReturn, ...)
Whatever works... perhaps I need some kind of macro that allows me to extract some macro at some position, like ARG_1(...) etc, but so far I can't wrap it all that in my brain how to do it.
PS. I recall some super cool examples on usage of c-preprocessor with very good explanation here in SO, but can't find them now, if you have it bookmarked, maybe all I need is to look into them.
EDIT: Basically, the trick is to add auto-numbered names to each argument and then pass them as-is to a member function. The reason I need it done this way is because on top of all that I have some other autogeneration done with preprocessor. In short, this macro will actually be used in a group of similar macro (something like in 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()
class TestClass { ... }
cannot be C; it can only be C++. So, you should probably tag your question as C++. The other tag is fine. You should look up the Boost Preprocessor code before deciding what can and cannot be done. – Jonathan Leffler