JNI JNA可以調用C++嗎?


其實JNI有兩個版本,一個是給C用的一個是給C++用的。例如說同樣的JNI CallVoidMethod函數:

C版:

// JNIEnv* env
(*env)-&>CallVoidMethod(env, obj, mid, arg);

C++版:

// JNIEnv* env
env-&>CallVoidMethod(obj, mid, arg);

所以JNI當然有考慮到跟C++搭配使用的情況。

在默認情況下,JVM在鏈接一個native方法時會根據JNI方法的命名規範去查找底下的實現函數,而這個命名規範用的是C linkage的。例如:

package my.stuff;

public class Foo {
public static native void bar(int i);
}

bar()方法根據命名規範就需要能鏈接到一個native函數:

void Java_my_stuff_Foo_bar(JNIEnv* env, jclass clazz, jint i);

而用這種默認命名規範時要用C linkage的話要麼用C語言,要麼在C++里用extern "C"來聲明這個函數。

但這並不是說就不能直接從JNI調用C++函數了。除了通過上述命名規範隱式(自動)註冊native函數給JVM之外,還可以通過JNI顯式(手動)註冊一個函數給JVM——調用RegisterNatives()函數:

jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods);

善用Google能搜出很多在C++里用RegisterNatives的例子,例如:

How can I make JNI RegisterNatives callack Java functions have C++ instance scope?

JNA方面,可以參考另一個爆棧帖:jni - Java Native Access doesn"t do C++, right?


C++ 的 ABI 太脆弱。你要保證自己用的和 Oracle 一樣。雖說不是做不到,但是沒啥必要惹這麻煩。


可以是可以,不過用C調用C++的庫需要一些麻煩的鏈接。


可以


extern "C"解決你的問題


可以參考SWIG是怎麼做的,封裝JNI介面的人看到這個工具,應該就是兩行熱淚流下來吧~


JNAerator 用頭文件生成java代碼,直接調java函數,傳約定的參數即可,多快好省,少走彎路,最近就做人臉識別,坑慘了。 句柄把虛擬機高崩潰,各種指針搞得暈頭轉向,還有擔心內存泄漏問題,一個禮拜封裝好介面,完美解決。


推薦閱讀:

有哪些常見的垃圾軟體?
如何給一個外行人解釋:世界上第一個程序是如何寫出來並讓它按規定運行?
卡內基梅隆大學(CMU)的Eric Xing(邢波)教授為什麼能讀完一般學校的分子生物學PhD後到伯克利去CS PhD?
VBA怎麼入門吖? 昨天看到一個入門文章 很不錯 但是想問問有木有更好的辦法

TAG:互聯網 | 編程 | 計算機 | JavaNativeInterface | C |