Easy JNI with variadic templates

After hours of struggling with small bugs in JNI code I got tired and wrote these variadic template wrappers for cocos2d-x JniHelper to make calling Java from C++ nice and easy

Here’s an example. Suppose we have a Java class

class Logger {
    public static void purchase(float sum, String currency) {
        // some code here
    }
}

Then we can call it from C++ with just one line of code

easyjni::callVoidMethod("path/to/Logger", "purchase", float(3.14), "USD");

There can be any number of arguments and the method signature is automatically inferred under the hood with template magic. Supported argument data types are: bool, char, short, int, long, float, double, char* and std::string. Make sure the arguments on the Java side have corresponding primitive types (no Boolean, Integer, etc), except for char* and std::string, corresponding Java type for them is String.

One thing to note is that it should be obvious for the compiler to infer template types, otherwise incorrect signature might be generated and JNI won’t be able to find the method you are trying to call. This can be achieved with three different approaches:

  1. Using variables as parameters, i.e.

    float sum = 3.14;
    std::string currency = “USD”;
    easyjni::callVoidMethod(“path/to/Logger”, “purchase”, sum, currency);

  2. With implicit casts:

    easyjni::callVoidMethod(“path/to/Logger”, “purchase”, float(3.14), “USD”);

  3. And with implicit template instantiation

    easyjni::callVoidMethod<float, std::string>(“path/to/Logger”, “purchase”, 3.14, “USD”);

4 Likes

:+1: This should be integrated into cocos2dx. Could you make a pr for this.

this is a good idea :smile:

I would change signature of functions to specify they are static method invocations tho.

@Dredok @Victor_K it would probably be the best idea to add them to JniHelper and name them like

callStaticVoidMethod

@ricardo, what do you think?

Looks nice

I really like the way to call the methods , nice job

I will give it a try , and i will try use it to integrate appodeal sdk (android) for cocos2dx

Best regards

@Victor_K
yeah. I like them.

@pandamicro
Can we add them in v3.9 or 3.10?

@ricardo After 3.9 comes 3.10, 3.11 etc. not 4.0?

@TheCodez major numbers are changed when a major version (think if big refactoring a possible breaking backward compatibility) is released. we are not planning that at the moment.

Here’s the pr: https://github.com/cocos2d/cocos2d-x/pull/14340

@Victor_K Thanks, great feature !
@ricardo Can you review the PR ?

I think it could be scheduled into v3.10

looks good to me. I added my comments. Basically I would add a tests that shows how to call system libraries… like creating a native button or something like that.

Sorry for bother old topic, but is there any reason why its not in release? There are any drawback or …?
Use this in two major projects, many many thanks to the author - almost all the pain from marshaling go away.

Thank you for the kind words :slight_smile: This code was actually merged into master about a year ago https://github.com/cocos2d/cocos2d-x/blob/v3/cocos/platform/android/jni/JniHelper.h

Cool! Not found it before because was looking for easy jni namespace, sorry. Perhaps need to more read cocos code, than this forum for outdated examples in another threads))