C/C++和Java的交互详解
C/C++和Java的交互详解
发布时间:2016-12-28 来源:查字典编辑
摘要:安卓中支持c++(NDK)和java(SDK)语言,当使用到c++语言时,c++代码和java如何交互就尤为重要。在下载的NDK包中samp...

安卓中支持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 <stdio.h> #include <stdlib.h> #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

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Java学习
热门Java学习
编程开发子分类