Using JNI with more than one parameter


#1

Hi,

I have this code working on my project, I use JNI to open a url im my game,
I found this code in this site

void openURLJNI(const char* url)
    {
        JniMethodInfo t;
        if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxActivity" 
                        ,"openURL" 
                        ,"(Ljava/lang/String;)V"))
        {
            jstring StringArg1 = t.env->NewStringUTF(url);
            t.env->CallStaticVoidMethod(t.classID,t.methodID, StringArg1);
        }

    }

But now I want to pass more parameters, for example:

void doSomething(const char* title, const char* message, int number )

But I don’t know how I can send these parameters using the code:

jstring StringArg1 = t.env->NewStringUTF(url);
t.env->CallStaticVoidMethod(t.classID,t.methodID, StringArg1);

#2

java

static void testJNI(final String arg1, final String arg2, final int arg3) {
  Log.i("TestJNI", "arg1 = " + arg1 + ", arg2 = " + arg2 + ", arg3 = " + arg3);
}

c++

void doSomething(const char* title, const char* message, int number ) {
  JniMethodInfo t;
  if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxActivity" 
                        ,"testJNI" 
                        ,"(Ljava/lang/String;Ljava/lang/String;I)V"))
    jstring StringArg1 = t.env->NewStringUTF(title);
    jstring StringArg2 = t.env->NewStringUTF(message);
    t.env->CallStaticVoidMethod(t.classID,t.methodID, StringArg1, StringArg2, number);
    t.env->DeleteLocalRef(stringArg1);
    t.env->DeleteLocalRef(stringArg2);
    t.env->DeleteLocalRef(methodInfo.classID);
  }
}

#3

On the java side I create two codes

public static void doSomething(String title){
        Log.d("xxx", "xxx");
}

public static void doSomething(String title,String message,int number){
        Log.d("zzz", "zzz");
}

But the app only call the first, I think there’s something that I forgot that change in the following code:

if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxActivity"
                            ,"sendScore"
                            ,"(Ljava/lang/String;)V"))

#4

I finally make the code work.

I use this:

void sendScoreJNI(const char* name, const char* difficulty,  const char* score)
        {
            JniMethodInfo t;
            if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxActivity"
                            ,"sendScore"
                            ,"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"))
            {
                jstring StringArg1 = t.env->NewStringUTF(name);
                jstring StringArg2 = t.env->NewStringUTF(difficulty);
                jstring StringArg3 = t.env->NewStringUTF(score);
                t.env->CallStaticVoidMethod(t.classID,t.methodID, StringArg1, StringArg2, StringArg3);
            }

        }

This line is where you specify how many parameters you will send to the static method in java.

,"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"))

#5

@Fabio
Can you please tell me how did you pass an int parameter? and what should I do if I dont want to pass any parameter to the java function? just call the java function??


#6

Without parameter

c*+ side
<pre>
void testJNI
{
JniMethodInfo t;
if V“))
{
t.env~~>CallStaticVoidMethod;
}
}
</pre>
java side
<pre>
public static void sendTest{
Log.d;
}
</pre>
using int parameter
c++ side
<pre>
void testIntJNI
{
JniMethodInfo t;
if V"))
{
t.env~~>CallStaticVoidMethod(t.classID,t.methodID,number);
}
}
</pre>
java side
<pre>
public static void sendTest(int i){
Log.d(”bbb“,”bbb"*i);
}


#7

Thnks for the reply … that was very helpful …:slight_smile:


#8

and how to get android app response to my cocos2d-x app?


#9

I never try to do that before, but using my example, just change the void keyword with the type of response that you want.

Example: a boolean

c*+ side
<pre>
bool testIntJNI
{
JniMethodInfo t;
if V“))
{
t.env->CallStaticVoidMethod(t.classID,t.methodID,number);
}
}
</pre>
java side
<pre>
public static bool sendTest(int i){
Log.d(”bbb“,”bbb"*i);
return true;

}

Don’t forget to mark the c++ method with the ‘external’ keyword in your .h file.

I don’t test this code, but I think it will work.


#10

thanks for you message :slight_smile:
but may by this as next

if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxActivity"
,"sendTest"
,"(I)B")) {
t.env->CallStaticBoolMethod(t.classID,t.methodID,number);

#11

Alex Merfi wrote

but may by this as next

Sorry, but I do not understand what you mean


#12

no problem :slight_smile:
For your example:

“(I)V”) => ,“(I)B”))
t.env~~>CallStaticVoidMethod( => t.env~~>CallStaticBoolMethod(


#13

Now I understand what you mean.
Based in what you wrote, I suppose the code works for you, I’m right?


#14

your example isn’t working:

bool testIntJNI(int number)
{
    JniMethodInfo t;
    if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxActivity" 
                    ,"sendTest" 
                    ,"(I)V"))
    {
        t.env->CallStaticVoidMethod(t.classID,t.methodID,number);
    }

}

Becose argument V in “(I)V” - this is VOID result. If you try to run the code - you receive an error.
For returned bool value we should specify this as “(I)B” (B - bool) and call CallStaticBoolMethod.

:slight_smile:
I am sorry for my English


#15

thanks for clarify things,

I understand in your previous response that my code is not working, I only ask if your code(the modified version that you create) has work.
But based in what you say, I could conclude that works.