user2127615
user2127615

Reputation: 21

How can I send cpp callback function pointer to java

I am working on android application which is written in cpp (cocos2dx) Now I'm doing a facebook module which has to be implemented in java.

The facebook calls are asynchronic so I cannot know when the action is completed unless I'll have a callback from the java part to the cpp.

For example:

The JNI part should look like something like that:

void CCAndroidApplication::login2Facebook()
{
    JniMethodInfo minfo;
    if(JniHelper::getStaticMethodInfo(minfo,
        "org/cocos2dx/example/myandroidtest",
        "login2Facebook",
        "(**POINTER TO CALLBACK METHOD DidLogin()**)V")) 
    {
        minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
        minfo.env->DeleteLocalRef(minfo.classID);
    }
}

and the java part should look like:

public static void login2Facebook(**POINTER TO native CALLBACK METHOD DidLogin()**) 
    Session.openActiveSession(me, true, new Session.StatusCallback() 
    {
        @Override
        public void call(Session session, SessionState state, Exception exception) 
        {
            mSession = session;
            if (session.isOpened()) 
            {
                Request.executeMeRequestAsync(session, new Request.GraphUserCallback() 
                {
                    @Override
                    public void onCompleted(GraphUser user, Response response) 
                    {
                        if (user != null) 
                        {
                            **Call nativeDidLogin()**;
                        }
                    }
                });
            }
        }
    });
}

It is also fine if I can send cpp object that contains the method like

class delgateMethods
{
public:
    void didLogin();
}

and call it from the java.

My question is: Is it possible to send a pointer to function over the JNI and call it in the java part?

Thanks

Upvotes: 2

Views: 1484

Answers (2)

Samuel Audet
Samuel Audet

Reputation: 4994

If I understand correctly, an interface like this should do what you need with JavaCPP:

@Platform(library="Facebook")
public class Facebook {
    public static class DidLogin extends FunctionPointer {
        public native void call();
    }

    public static class Login2Facebook extends FunctionPointer {
        public @Name("login2Facebook") void call(DidLogin didLogin) { 
            didLogin.call()
        }
    }
}

And from C/C++ we can call login2Facebook() by name:

#include "jniFacebook.h"
void didLogin() { /* Did we? */ }
int main() {
    JavaCPP_init(0, NULL); // or initialize the JVM some other way
    login2Facebook(didLogin);
    JavaCPP_uninit();
}

Upvotes: 2

Omnifarious
Omnifarious

Reputation: 56048

I don't remember precisely how JNI works. But what you'll have to do is create a class that holds the callback pointer that's a hybrid Java/C++ class using JNI. That class will have to derive from a Java interface that describes the function signature of the callback. This interface likely already exists because that's a common pattern for callbacks in Java.

There is no way to directly represent a C/C++ function pointer in Java.

Upvotes: 1

Related Questions