安卓中支持c++(ndk)和java(sdk)语言,当使用到c++语言时,c++代码和java如何交互就尤为重要。在下载的ndk包中samples/hello-jni有一个简单的实例可以参考。
java调用c++
新建android项目,创建如下类:
package com.example.testjni;
public class textjni {
// support to c
static {
system.loadlibrary("jniinterface");
}
public static native int getint();
public static native string getstring();
}
上面声明了两个native方法,表示getint和getstring的方法实现将在c++(libjniinterface.so)中给出。
在classes目录下运行如下命令,以生成native对应的实现文件。
javah com.example.testjni.textjni
# 注意如果要有android sdk的类需要指定classpath, 如
javah -classpath /users/richard/dev/android/sdk/platforms/android-19/android.jar:./bin/classes com.togic.gameengine.gfrenderer
生成头文件拷贝出来,创建jni文件夹,并创建出cpp实现文件
com_example_testjni_textjni.cpp:
#include
#include
#include "com_example_testjni_textjni.h"
int sum ()
{
int x,y;
x = 100 ;
y = 1000;
x += y;
return x;
}
//实现 com_example_textjni_textjni.h 的方法
jniexport jint jnicall java_com_example_testjni_textjni_getint(jnienv * env, jclass cls)
{
return sum();
}
jniexport jstring jnicall java_com_example_testjni_textjni_getstring(jnienv * env, jclass cls)
{
return env->newstringutf("hellondk!");
}
这里要用到交叉编译,组织c++代码需要用android.mk。
新建一个android.mk文件在jni/下
android.mk:
local_path := $(call my-dir)
include $(clear_vars)
local_module := jniinterface
local_src_files := com_example_testjni_textjni.cpp
#local_c_includes := $(local_path)
include $(build_shared_library)
然后就可以用ndk里的工具:ndk-build来生成动态链接库:libjniinterface.so
生成的库文件就可以被之前的java文件调用了。
c++ 调用 java
可以在上例中getstring方法里利用jni调用java:
jniexport jstring jnicall java_com_togic_testjni2_textjni_getstring(jnienv * env, jclass cls)
{
jclass textjni;
jobject insttextjni;
jmethodid getcurrint;
jnienv* jnienv = env;
textjni = jnienv->findclass("com/togic/testjni2/textjni");
jmethodid construction_id = jnienv->getmethodid(textjni, "init", "()v");
insttextjni = jnienv->newobject(textjni, construction_id);
getcurrint = jnienv->getstaticmethodid(textjni, "getcurrint","()i");
// call java static method
jint jiref = jnienv->callstaticintmethod(textjni, getcurrint);
// clean
jnienv->deletelocalref(textjni);
jnienv->deletelocalref(insttextjni);
std::string strref = "hellondk!" + view->getstaticstring();
return env->newstringutf(strref.c_str());
}
首先值得注意的是jni.h里的函数区分c和c++语言两种接口,对于c++一般如下:
jclass clazz = env->findclass(classname);
而对于c而言:
jclass clazz = (*env)->findclass(env, classname);
getmethodid中第三个参数表示方法签名,可以按如下方法获得:
javap -s 包名.类名 得到方法的签名
附 jni数据类型转化
jstring 转 char *
const char nativestring = (env)->getstringutfchars(env, javastring, 0);
返回指向字符串的 utf-8 字符数组的指针,该数组在被 releasestringutfchars() 释放前将一直有效。
(*env)->releasestringutfchars(env, javastring, nativestring);
char * 转 jstring
jstring jstr = (env)->newstringutf(env, char utf)
利用 utf-8 字符数组构造新 java.lang.string 对象。
其他类型
全选复制放进笔记java 类型 本地 c 类型 说明
boolean jboolean 无符号,8 位
byte jbyte 无符号,8 位
char jchar 无符号,16 位
short jshort 有符号,16 位
int jint 有符号,32 位
long jlong 有 符号,64 位
float jfloat 32 位
double jdouble 64 位
void void n/a
希望与广大网友互动??
点此进行留言吧!