Cocos2d-x
发布时间:2022-05-03 发布网站:大佬教程 code.js-code.com
大佬教程收集整理的这篇文章主要介绍了cocos2dx调用android代码,android调用c,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
转载自http://mysuperbaby.iteye.com/blog/915425
Java调用Native模块
Hello-JNI这个示例的结构很简单:首先我们使用Eclipse新建一个OPhone应用的Java工程,并添加一个 co
m.example.
Hellojni.
HelloJni的类。这个类实际上是一个Activity,稍后我们会创建一个TextView,并显示一 些文字在上面。
要在Java代码中
使用Native模块,必须先对Native函数进行声明。在我们的例子中,打开
HelloJni.java文件,可以看到如下的声明:
-
- *'Hello-jni'nativelibrary,whichispackaged
- *withthisapplication.
- */
- publicnativeStringStringFromJNI();
@H_
944_55@
:1em; margin:0px 0px 0px 38px; padding:0px 0px 0px 10px; border-left-width:1px; border-left-style:solid; border-left-color:rgb(209,whichispackaged
*/
nativeStringStringFromJNI();
从上述声明中我们
可以知道,这个
StringFromJNI()函数就是要在Java代码中调用的Native函数。接下来我们要创建一个
Hello-jni.c的C文件,内容很简单,只有如下一个函数:
#include<String.h>
#include<jni.h>
jString
Java_com_example_Hellojni_HelloJni_StringFromJNI(JNIEnv*env,
jobjectthiz){
return(*env)->NewStringUTF(env,"HellofromJNI!");
}
#include<jni.h>
:1em; margin:0px 0px 0px 38px; padding:0px 0px 0px 10px; border-left-width:1px; border-left-style:solid; border-left-color:rgb(209,
:1em; margin:0px 0px 0px 38px; padding:0px 0px 0px 10px; border-left-width:1px; border-left-style:solid; border-left-color:rgb(209,"HellofromJNI!");
}
从上面Native函数的命名上我们可以了解到JNI函数的命名规则: Java代码中的函数声明需要添加
native关键 字;Native的对应函数名要以“Java_”开头,后面依次跟上Java的“package名”、“class名”、“函数名”,中间以
下划线“_” 分割,在package名中的“.”也要改为“_”。此外,关于函数的参数和返回值也有
相应的规则。对于Java中的基本类型如
int、
double、
char等,
在Native端都
有相对应的类型来表示,如
jint、
jdouble、
jchar等;其他的对象类型则统统由
jobject来表示(
String是个例外,由于其使用广泛,故
在Native代码中有
jString这个类型来表示,正如在上例中返回值
String对应到Native代码中的返回值
jString)。而对于Java中的数组,
在Native中由
jarray对应,具体到基本类型和一般对象类型的数组则有
jintArray等和
jobjectArray分别对应(
String数组在这里没有例外,同样用
jobjectArray表示)。
还有一点
需要注意的是,在JNI的Native函数中,其前两个参数
JNIEnv*和
jobject是必需的——前者是一个
JNIEnv结构体的指针,这个结构体中定义了很多JNI的接口函数指针,使开发者可以使用JNI所定义的接口功能;后者指代的是调
用这个JNI函数的Java对象,有点类似于C++中的
this指针。在上述两个参数之后,还需要根据Java端的函数声明依次对应添加参数。在上例中,Java中声明的JNI函数没有参数,
则native的对应函数只有类型为
JNIEnv*和
jobject的两个参数。
当然,要使用JNI函数,还需要先加载Native代码编译出来的动态库文件(在Windows上是.dll,在Linux上则为.so)。这个动作是通过如下语句完成的:
static
{
System.loadLibrary("Hello-jni");
System.loadLibrary("Hello-jni");
}
注意这里调用的共享库名遵循Linux对库文件的命名惯例,因为OPhone的核心实际上是Linux系统——上例中,实际加载的库文件应为 “lib
Hello-jni.so”,在引用时遵循命名惯例,不带“lib”前缀和“.so”的扩展名。对于没有按照上述惯例命名的Native库,在加 载时仍需要写成完整的文件名。
JNI函数的使用方法和普通Java函数一样。
在本例中,调用代码如下:
TextViewtv=newTextView(this);
tv.setText(StringFromJNI());
setContentView(tv);
tv.setText(StringFromJNI());
setContentView(tv);
就可以在TextView中显示出来自于Native函数的字符串。怎么样,
是不是很简单呢?
Native调用Java模块
从OPhone的系统架构来看,JVM和Native系统库位于内核之上,构成OPhone Runtime;更多的系统功能则是通过在其上的Application Framework以Java API的形式提供的。因此,如果希望
在Native库中调用某些系统功能,就需要通过JNI来访问Application Framework提供的API。
JNI规范定义了一系列
在Native代码中访问Java对象及其成员与方法的API。下面我们还是通过示例来具体讲解。首先,新建一个
SayHello的类,代码如下:
packageco
m.example.
Hellojni;
classSayHello{
publicStringsayHelloFromJava(StringnativeMsg){
Stringstr=nativeMsg+"ButshowninJava!";
returnstr;
}
classSayHello{
Stringstr=nativeMsg+"ButshowninJava!";
}
接下来要实现的就是在Native代码中调用这个
SayHello类中的sayHelloFromJava方法。
一般来说,要
在Native代码中访问Java对象,有如下几个步骤:
1.得到该Java对象的类定义。JNI定义了
jclass这个类型来表示Java的类的定义,并提供了FindClass接口,根据类的完整的包路径即可得到其
jclass。
2.根据
jclass创建
相应的对象实体,即
jobject。在Java中,创建一个
新对象只需要使用
new关键字即可,但
在Native代码中创建一个对象则需要两步:首先通过JNI接口GetMethodID得到该类的构造函数,然后利用NewOb
ject接口构造出该类的一个实例对象。
3.访问
jobject中的成员变量或方法。访问对象的方法是先得到方法的Method ID,然后使用Call<
Type>Method 接口调用,这里Type对应相应方法的返回值——返回值为基本类型的都
有相对应的接口,如CallIntMethod;其他的返回值(包括
String) 则为CallOb
jectMethod。
可以看出,创建对象实质上是调用对象的一个特殊方法,即构造函数。访问成员变量的步骤一样:首先 GetFieldID得到成员变量的ID,然后Get/Set<
Type>Field读/写变量值。
上面概要介绍了从Native代码中访问Java对象的过程,下面我们结合示例来具体看一下。如下是调用say
HelloFromJava方法的Native
代码:
jStringHelloFromJava(JNIEnv*env){
jStringstr=NULL;
jclassclz=(*env)->FindClass(env,"com/example/Hellojni/SayHello");
jmethodIDctor=(*env)->GetMethodID(env,clz,"<init>","()V");
jobjectobj=(*env)->NewObject(env,ctor);
jmethodIDmid=(*env)->GetMethodID(env,"sayHelloFromJava","(Ljava/lang/String;)Ljava/lang/String;");
if(mid){
jStringjmsg=(*env)->NewStringUTF(env,"I'mborninnative.");
str=(*env)->CallObjectMethod(env,obj,mid,jmsg);
}
returnstr;
jStringstr=NULL;
:1em; margin:0px 0px 0px 38px; padding:0px 0px 0px 10px; border-left-width:1px; border-left-style:solid; border-left-color:rgb(209,"()V");
:1em; margin:0px 0px 0px 38px; padding:0px 0px 0px 10px; border-left-width:1px; border-left-style:solid; border-left-color:rgb(209,"(Ljava/lang/String;)Ljava/lang/String;");
:1em; margin:0px 0px 0px 38px; padding:0px 0px 0px 10px; border-left-width:1px; border-left-style:solid; border-left-color:rgb(209,"I'mborninnative.");
可以看到,上述代码和前面讲到的步骤完全相符。这里提一下编程时要注意的要点:1、FindClass要写明Java类的完整包路径,并将 “.”以“/”替换;2、GetMethodID的第三个参数是方法名(对于构造函数一律用“<init>”表示),第四个参数是方法的“签 名”,需要用一个字符串序列表示方法的参数(依声明顺序)和返回值信息。由于篇幅所限,这里不再具体说明如何根据方法的声明构造相应的“签名”,请参考 JNI的相关文档。
关于上面谈到的步骤再
补充说明一下:在JNI规范中,如上这种
使用NewOb
ject创建的对象实例被称为“Local Reference”,它仅在创建它的Native代码作用域内有效,因此应避免在作用域外使用该实例及任何指向它的指针。如果希望创建的对象实例在作用 域外也能使用,则需要
使用NewGlobalRef接口将其提升为“Global Reference”——
需要注意的是,当Global Reference不再使用后,需要显式的释放,以
便通知JVM进行垃圾收集。
大佬总结
以上是大佬教程为你收集整理的cocos2dx调用android代码,android调用c全部内容,希望文章能够帮你解决cocos2dx调用android代码,android调用c所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。