Reputation: 44104
I have a list of functions:
JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_staticInit(JNIEnv* env, jclass clazz);
JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_gc(JNIEnv* env, jobject obj);
JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_adjustExternalMemory(JNIEnv* env, jobject obj, jint bytes);
JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_init(JNIEnv* env, jobject obj);
JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_runScript(JNIEnv* env, jobject obj, jstring code, jstring name);
JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_callFunction(JNIEnv* env, jobject obj, jstring name);
JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_callFunctionD(JNIEnv* env, jobject obj, jstring name, jdouble d);
I'm trying to get rid of some duplication by using a define
:
#define JNIFUNC JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity
JNIFUNC_staticInit(JNIEnv* env, jclass clazz);
JNIFUNC_gc(JNIEnv* env, jobject obj);
JNIFUNC_adjustExternalMemory(JNIEnv* env, jobject obj, jint bytes);
JNIFUNC_init(JNIEnv* env, jobject obj);
JNIFUNC_runScript(JNIEnv* env, jobject obj, jstring code, jstring name);
JNIFUNC_callFunction(JNIEnv* env, jobject obj, jstring name);
JNIFUNC_callFunctionD(JNIEnv* env, jobject obj, jstring name, jdouble d);
However, this does not result in the desired output, presumably because JNIFUNC_something
is not recognized as a reference to JNIFUNC
.
Can I accomplish what I want?
Upvotes: 1
Views: 73
Reputation: 29126
The C preprocessor is a simple text replacement tool, but the text to replace must be a whole word (in the sense of a C symbol). Your macro JNIFUNC
is not recognised when it is part of, say, JNIFUNC_gc
.
You can use the token pasting syntax for macros, ##
, to create new symbols. In your case, you could define:
#define JNIFUNC(name) JNIEXPORT void \
JNICALL Java_weber_droidtilla_DTActivity_##name
JNIFUNC(staticInit)(JNIEnv* env, jclass clazz);
JNIFUNC(gc)(JNIEnv* env, jobject obj);
JNIFUNC(adjustExternalMemory)(JNIEnv* env, jobject obj, jint bytes);
Or, if you are willing to exploit the pattern of duplications even more, you could use variadic macro arguments to get rid of the first pair of parentheses:
#define JNIFUNC(name, ...) JNIEXPORT void \
JNICALL Java_weber_droidtilla_DTActivity_##name(JNIEnv *env, \
__VA_ARGS__)
JNIFUNC(staticInit, jclass clazz);
JNIFUNC(gc, jobject obj);
JNIFUNC(adjustExternalMemory, jobject obj, jint bytes);
Upvotes: 2
Reputation: 9991
Your preprocessor directive looks for the token JNIFUNC
. The token JNIFUNC_staticInit
is a completely different token even though it contains the same substring. You can put a space instead of an underscore for your functions like JNIFUNC staticInit
which will make the preprocessor replace the token but the result would be Java_weber_droidtilla_DTActivity staticInit
(note the space) which would most likely result in a syntax error.
The c++ solution is a namespace:
namespace Java_weber_droidtilla_DTActivity{
void staticInit(...);
}
For c you could do something like this (also works in c++):
#define JNIFUNC(X) JNIEXPORT void JNICALL Java_weber_droidtilla_DTActivity_##X
JNIFUNC(staticInit)(JNIEnv* env, jclass clazz);
Upvotes: 2