C/C++和Java的交互詳解
安卓中支持c++(NDK)和java(SDK)語(yǔ)言,當(dāng)使用到c++語(yǔ)言時(shí),c++代碼和java如何交互就尤為重要。在下載的NDK包中samples/hello-jni有一個(gè)簡(jiǎn)單的實(shí)例可以參考。
java調(diào)用C++
新建Android項(xiàng)目,創(chuàng)建如下類:
package com.example.testjni; public class TextJni { // support to c static { System.loadLibrary("jniinterface"); } public static native int getInt(); public static native String getString(); }
上面聲明了兩個(gè)native方法,表示getInt和getString的方法實(shí)現(xiàn)將在c++(libjniinterface.so)中給出。
在classes目錄下運(yùn)行如下命令,以生成native對(duì)應(yīng)的實(shí)現(xiàn)文件。
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
生成頭文件拷貝出來(lái),創(chuàng)建jni文件夾,并創(chuàng)建出cpp實(shí)現(xiàn)文件
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; } //實(shí)現(xiàn) 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。
新建一個(gè)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來(lái)生成動(dòng)態(tài)鏈接庫(kù):libjniinterface.so
生成的庫(kù)文件就可以被之前的Java文件調(diào)用了。
c++ 調(diào)用 java
可以在上例中g(shù)etString方法里利用JNI調(diào)用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里的函數(shù)區(qū)分c和c++語(yǔ)言兩種接口,對(duì)于c++一般如下:
jclass clazz = env->FindClass(classname);
而對(duì)于c而言:
jclass clazz = (*env)->FindClass(env, classname);
GetMethodID中第三個(gè)參數(shù)表示方法簽名,可以按如下方法獲得:
javap -s 包名.類名 得到方法的簽名
附 JNI數(shù)據(jù)類型轉(zhuǎn)化
jstring 轉(zhuǎn) char *
const char nativeString = (env)->GetStringUTFChars(env, javaString, 0);
返回指向字符串的 UTF-8 字符數(shù)組的指針,該數(shù)組在被 ReleaseStringUTFChars() 釋放前將一直有效。
(*env)->ReleaseStringUTFChars(env, javaString, nativeString);
char * 轉(zhuǎn) jstring
jstring jstr = (env)->NewStringUTF(env, char utf)
利用 UTF-8 字符數(shù)組構(gòu)造新 java.lang.String 對(duì)象。
其他類型
全選復(fù)制放進(jìn)筆記Java 類型 本地 c 類型 說明
boolean jboolean 無(wú)符號(hào),8 位
byte jbyte 無(wú)符號(hào),8 位
char jchar 無(wú)符號(hào),16 位
short jshort 有符號(hào),16 位
int jint 有符號(hào),32 位
long jlong 有 符號(hào),64 位
float jfloat 32 位
double jdouble 64 位
void void N/A
- 人工智能開發(fā)語(yǔ)言排行榜: 不死Java, 不朽C/C++, 新貴Python【推薦】
- Java通過調(diào)用C/C++實(shí)現(xiàn)的DLL動(dòng)態(tài)庫(kù)——JNI的方法
- JNI實(shí)現(xiàn)最簡(jiǎn)單的JAVA調(diào)用C/C++代碼
- Android JNI c/c++調(diào)用java的實(shí)例
- C/C++在Java、Android和Objective-C三大平臺(tái)下實(shí)現(xiàn)混合編程
- 如何批量清理系統(tǒng)臨時(shí)文件(語(yǔ)言:C#、 C/C++、 php 、python 、java )
- java和c/c++ 數(shù)據(jù)類型長(zhǎng)度的比較
- C/C++與Java各數(shù)據(jù)類型所占字節(jié)數(shù)的詳細(xì)比較
- Mac下用Java調(diào)用c/c++的思路詳解
相關(guān)文章
Java中Random簡(jiǎn)介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
本文詳細(xì)給大家介紹了Java中Random簡(jiǎn)介相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-06-06Spring Cloud如何使用Feign構(gòu)造多參數(shù)的請(qǐng)求
這篇文章主要介紹了Spring Cloud如何使用Feign構(gòu)造多參數(shù)的請(qǐng)求,以GET以及POST方法的請(qǐng)求為例進(jìn)行講解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03java如何接收和發(fā)送ASCII數(shù)據(jù)
這篇文章主要介紹了java如何接收和發(fā)送ASCII數(shù)據(jù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09Java集合Map常見問題_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)整理了Java集合Map常見問題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05