cocos2dx jni 的使用
前端之家收集整理的这篇文章主要介绍了
cocos2dx jni 的使用,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
jni的意思是java本地调用,通过jni可以实现java层代码和其他语言写得代码进行交互。在cocos2d-x中,如果想要在c++层调用java层的代码,就是通过jni技术。通过调用java层的代码,我们就可以在Android平台下实现一些引擎没有提供给我们的功能,或者做一些其他的功能。比如加个广告,加个分享,调用Android原生的对话框等等吧。Cocos2d-x比较人性化的是为我们封装了jni调用的一些接口,这个类就是JniHelper,我们只需要使用这个类提供给我们的接口就可以完成调用java层代码的功能。先说一下这个类的位置,因为自己在找的时候有点犯二,所以特意说明一下。在3.0和3.1以上的引擎版本中,这个类的位置分别如下。
3.1以后引擎把原来cocos目录下的包含各个功能的文件夹都放到了cocos目录下,我个人认为这样的放法还是比较好的。就是引擎老改目录,希望以后不要放来放去了。最主要的当然是看看怎么使用JniHelper这个类了。
首先使用之前要包含头文件,写法如下,记住要加上条件编译,这个东西是Android平台下才用到。
1 |
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) |
@H_
301_32@
3 |
#include "platform/android/jni/JniHelper.h" |
4
#include <jni.h> |
6
#endif |
接着通过一小段代码来说明一下这个类的用法。
// JNIEnv * env;
// jmethodID methodID;
8
9 |
JniMethodInfo info; |
10
11 |
|
12
bool ret = JniHelper::getStaticMethodInfo(info, "org/cocos2dx/cpp/TestJni" ,monospace!important; border:0px!important; color:blue!important; font-size:1em!important; padding:0px!important; margin:0px!important; outline:0px!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:auto!important; line-height:1.1em!important; direction:ltr!important; display:inline!important">"func1" "()V" ); |
14
{ |
15 |
log ( "call void func1() succeed" ); |
16
//传入类ID和方法ID,小心方法名写错,第一个字母是大写 |
17 |
info.env->CallStaticVoidMethod(info.classID,info.methodID); |
18
} |
importandroid.util.Log;
publicclass
TestJni
static
void
func1()
Log.e("xiaota"
"java:func1,called succeed!"
int
func2()
return3838438
;
staticString func3(
i)
String str ="get int value:"
+i;
20
21 |
String func4(String str) |
22
23 |
24 |
str; |
26
func5(a, b) |
28
c = a+b; |
然后打包到Android平台,我们使用USB连接上电脑,打开eclipse,进行调试,看看信息输出了没有。
好了,这样的话就把这个流程都说明白了,下面我们看一些细节的地方。
"android platform!"//调用的函数有返回值
"call int func2() succeed"//返回的int值,用jint类型来接收 |
jint iret = info.env->CallStaticIntMethod(info.classID,info.methodID);
"func2的返回值是%d"//调用的函数有参数有返回值,这里有坑,注意Ljava/lang/String;后边的; |
33 |
"func3""(I)Ljava/lang/String;" 34 |
35 |
36 |
"call int func3(int) succeed"37 |
//java层的类类型对应的是jobject,把需要传递的参数写到调用函数的后边 |
38
jobject jobj = info.env->CallStaticObjectMethod(info.classID,info.methodID,1438); |
42
"func4""(Ljava/lang/String;)Ljava/lang/String;" 43 |
44 |
45 |
"call string func4(string) succeed"46 |
jobject para = info.env->NewStringUTF("haha" 47 |
jstring jstr = (jstring)info.env->CallStaticObjectMethod(info.classID,para); |
48
//使用jstring2string函数将返回的jstring类型的值转化为c++中的string类型 |
49 |
std::string text = JniHelper::jstring2string(jstr); |
50
"%s"
51 |
52 |
53 |
//如果函数需要的参数是俩个或者是多个,可以采用如下的写法 |
54 |
"(II)I"55 |
56 |
57 |
"call int func5(int a,int b) succeed"58 |
59 |
"return value is %d"60 |
61 |
上边的代码主要还是那俩个函数调用的说明,getStaticMethodInfo的第四个参数如果是类类型,注意要使用的签名,后边的分号也要加,如果参数有多个,直接连起来书写就可以了。使用CallStaticMethod调用的时候注意一下参数和返回值的类型,传递参数的时候直接写到函数的后边,但是参数类型要正确,返回值使用对应的类型来接受,这个类型就是前面加一个j,比如java层返回的类型是int,那接受的类型就是jint,java层返回object,接受类型就是jobject。
以上是调用java的静态函数,接下来是非静态函数的调用。我将c++的代码和java的代码都贴出来。
"org/cocos2dx/cpp/TestJniHelper""getObj" "()Ljava/lang/Object;" //先获得类的对象,然后用这个对象去调用它的非静态函数 |
jobject jobj; |
"call static method"jobj = info.env->CallStaticObjectMethod(info.classID,0)!important; font-size:1em!important; padding:0px!important; margin:0px!important; outline:0px!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:auto!important; line-height:1.1em!important; direction:ltr!important; display:inline!important">//getMethodInfo判断java定义的类非静态函数是否存在,返回bool |
re = JniHelper::getMethodInfo(info,monospace!important; border:0px!important; color:blue!important; font-size:1em!important; padding:0px!important; margin:0px!important; outline:0px!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:auto!important; line-height:1.1em!important; direction:ltr!important; display:inline!important">"func"(re) |
"call no-static method"//非静态函数调用的时候,需要的是对象,所以与静态函数调用的第一个参数不同 |
info.env->CallVoidMethod(jobj,monospace!important; border:0px!important; font-size:1em!important; padding:0px!important; margin:0px!important; outline:0px!important; float:none!important; vertical-align:baseline!important; position:static!important; left:auto!important; top:auto!important; right:auto!important; bottom:auto!important; height:auto!important; width:auto!important; line-height:1.1em!important; direction:ltr!important; display:inline!important">}