當前位置:首頁 » 編程語言 » jnic調用java

jnic調用java

發布時間: 2024-04-28 20:09:24

『壹』 怎樣用 jni來交互java與 c/c++

JNI是Java Native Interface的縮寫,中文為JAVA本地調用。使用JNI可以很方便的用我們的Java程序調用C/C++程序。很多時候,某些功能用Java無法實現,比如說涉及到底層驅動的一些功能,這時候我們就可以利用JNI來調用C或者C++程序來實現,這就是JNI的強大之處。但是JNI也有它的缺點,使用java與本地已編譯的代碼交互,通常會喪失平台可移植性。
下面是一個JNI例子,調用C++輸出"hello world":

第一步:創建Java類,在裡面定義一個本地方法(用native關鍵字修飾的方法)
public native void sayHello();
第二步:使用javah命令(javah 類的全路徑)生成本地方法的C++頭文件
在DOS窗口中進入工程所在目錄,然後執行javah com.test.TestNative命令,執行完之後就會在當前目錄生成一個後綴名為.h的頭文件,如com_test_TestNative.h,這個頭文件是根據包名和類名來命名的。

1 /* DO NOT EDIT THIS FILE - it is machine generated */
2 #include <jni.h>
3 /* Header for class com_test_TestNative */
4
5 #ifndef _Included_com_test_TestNative
6 #define _Included_com_test_TestNative
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10 /*
11 * Class: com_test_TestNative
12 * Method: sayHello
13 * Signature: ()V
14 */
15 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello
16 (JNIEnv *, jobject);
17
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif

15、16行是對TestNative類中的本地方法sayHello()的聲明。這個h文件相當於我們在java裡面的介面,這里聲明了一個 Java_com_test_TestNative_sayHello (JNIEnv *, jobject);方法,然後在我們的本地方法裡面實現這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這里的一致。
第三步:編寫C/C++本地代碼,生成動態鏈接庫文件
首先在VC6.0(當然也可以用其他工具)中創建一個dll工程---Win32 Dynamic-Link Library工程。然後將上面生成的頭文件com_test_TestNative.h添加到該工程中,然後創建一個源文件引用該頭文件並且實現頭文件中本地函數的功能:

1 #include<iostream.h>
2 #include"com_test_TestNative.h"
3
4 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello(JNIEnv *env, jobject obj)
5 {
6 cout<<"hello world!"<<endl;
7 }

這里因為com_test_TestNative.h中引入了jni.h所以要將jni.h加入到VC6.0安裝目錄下的Include目錄中。jni.h在JDK安裝目錄下的include中,同時得件include/win32中的兩個頭文件jawt_md.h、jni_md.h也導入到VC6.0中。
將所依賴的頭文件導入之後,我們就可以構建該工程了,按F7就行了,完了會在工程目錄中的Degug目錄下生成一個動態鏈接庫文件,我這里生成的是NativeCode.dll。我們就可以將該dll文件拷貝到環境變數path所包含的目錄下給咱們的Java程序調用了,為了方便,我們也可以將dll所在的工程目錄加入到環境變數path中去,這樣可以避免每次都要拷貝的麻煩。注意修改環境變數之後要重啟myeclipse。

第四步:Java調用本地函數

1 package com.test;
2
3 public class TestNative {
4 public native void sayHello();
5
6 /**
7 * @param args
8 */
9 public static void main(String[] args) {
10 System.loadLibrary("NativeCode");
11 TestNative tNative = new TestNative();
12 tNative.sayHello();
13 }
14 }

第10行是載入動態鏈接庫,JVM只需要載入一次就可以調用了,「NativeCode」是上面生成的動態鏈接庫的名字,不含後綴名。
運行該程序,成功列印輸出了"hello world"。

『貳』 如何在c++中調用java代碼

C語言調用Java,還有Java調用C,都使用到JNI技術,C語言調用需要創建Java虛擬機,可查看函數JNI_CreateJavaVM、DestroyJavaVM的資料,函數聲明在jni.h頭文件(JDK)中。需注意參數類型轉換,兩種語言的參數類型和傳遞有講究,有多個返回的話,必須傳遞對象參數進行處理。

『叄』 濡備綍鍦–/C++涓璋冪敤Java鐨勬柟娉

JNI鍏佽告偍浠庢湰鏈轟唬鐮佸唴璋冪敤 Java 綾繪柟娉曘

瑕佸仛鍒拌繖涓鐐癸紝閫氬父蹇呴』浣跨敤 Invocation API 鍦ㄦ湰鏈轟唬鐮佸唴鍒涘緩鍜屽垵濮嬪寲涓涓 JVM銆

涓嬪垪鏄鎮ㄥ彲鑳藉喅瀹氫粠 C/C++ 浠g爜璋冪敤Java 浠g爜鐨勫吀鍨嬫儏鍐碉細

1.甯屾湜瀹炵幇鐨勮繖閮ㄥ垎浠g爜鏄騫沖彴鏃犲叧鐨勶紝瀹冨皢鐢ㄤ簬璺ㄥ氱嶅鉤鍙頒嬌鐢ㄧ殑鍔熻兘銆

2.闇瑕佸湪鏈鏈哄簲鐢ㄧ▼搴忎腑璁塊棶鐢 Java 璇璦緙栧啓鐨勪唬鐮佹垨浠g爜搴撱

3.甯屾湜浠庢湰鏈轟唬鐮佸埄鐢ㄦ爣鍑 Java 綾誨簱銆
浠嶤/C++ 紼嬪簭璋冪敤 Java 浠g爜鐨勫洓涓姝ラわ細

1.緙栧啓 Java 浠g爜銆

榪欎釜姝ラゅ寘鍚緙栧啓涓涓鎴栧氫釜 Java 綾伙紝榪欎簺綾誨疄鐜幫紙鎴栬皟鐢ㄥ叾瀹冩柟娉曞疄鐜幫級鎮ㄦ兂瑕佽塊棶鐨勫姛鑳姐

2.緙栬瘧 Java 浠g爜銆

鍦ㄨ兘澶熶嬌鐢ㄨ繖浜 Java 綾諱箣鍓嶏紝蹇呴』鎴愬姛鍦板皢瀹冧滑緙栬瘧鎴愬瓧鑺傜爜銆

3.緙栧啓 C/C++ 浠g爜銆

榪欎釜浠g爜灝嗗壋寤哄拰瀹炰緥鍖 JVM錛屽苟璋冪敤姝g『鐨 Java 鏂規硶銆

4.榪愯屾湰鏈 C/C++ 搴旂敤紼嬪簭銆
灝嗚繍琛屽簲鐢ㄧ▼搴忎互鏌ョ湅瀹冩槸鍚︽e父宸ヤ綔銆傛垜浠榪樺皢璁ㄨ轟竴浜涚敤浜庡勭悊甯歌侀敊璇鐨勬妧宸с

『肆』 C調用java時使用JNI的問題!急。。。。。

M,是其中的一個組成部分,更詳細的看下面:

----------------------------------
操作系統裝入jvm是通過jdk中java.exe來完成,通過下面4步來完成jvm環境.
1.創建jvm裝載環境和配置
2.裝載jvm.dll
3.初始化jvm.dll並掛界到JNIENV(JNI調用介面)實例
4.調用JNIEnv實例裝載並處理class類。

在我們運行和調試java程序的時候,經常會提到一個jvm的概念.jvm是java程序運行的環境,但是他同時一個操作系統的一個應用程序一個進程,因此他也有他自己的運行的生命周期,也有自己的代碼和數據空間.
首先來說一下jdk這個東西,不管你是初學者還是高手,是j2ee程序員還是j2se程序員,jdk總是在幫我們做一些事情.我們在了解java之前首先大師們會給我們提供說jdk這個東西.它在java整個體系中充當著什麼角色呢?我很驚嘆sun大師們設計天才,能把一個如此完整的體系結構化的如此完美.jdk在這個體系中充當一個生產加工中心,產生所有的數據輸出,是所有指令和戰略的執行中心.本身它提供了java的完整方案,可以開發目前java能支持的所有應用和系統程序.這里說一個問題,大家會問,那為什麼還有j2me,j2ee這些東西,這兩個東西目的很簡單,分別用來簡化各自領域內的開發和構建過程.jdk除了jvm之外,還有一些核心的API,集成API,用戶工具,開發技術,開發工具和API等組成
好了,廢話說了那麼多,來點於主題相關的東西吧.jvm在整個jdk中處於最底層,負責於操作系統的交互,用來屏蔽操作系統環境,提供一個完整的java運行環境,因此也就虛擬計算機. 操作系統裝入jvm是通過jdk中java.exe來完成,通過下面4步來完成jvm環境.
1.創建jvm裝載環境和配置
2.裝載jvm.dll
3.初始化jvm.dll並掛界到JNIENV(JNI調用介面)實例
4.調用JNIEnv實例裝載並處理class類。
一.jvm裝入環境,jvm提供的方式是操作系統的動態連接文件.既然是文件那就一個裝入路徑的問題,java是怎麼找這個路徑的呢?當你在調用java test的時候,操作系統會在path下在你的java.exe程序,java.exe就通過下面一個過程來確定jvm的路徑和相關的參數配置了.下面基於windows的實現的分析.
首先查找jre路徑,java是通過GetApplicationHome api來獲得當前的java.exe絕對路徑,c:\j2sdk1.4.2_09\bin\java.exe,那麼它會截取到絕對路徑c:\j2sdk1.4.2_09\,判斷c:\j2sdk1.4.2_09\bin\java.dll文件是否存在,如果存在就把c:\j2sdk1.4.2_09\作為jre路徑,如果不存在則判斷c:\j2sdk1.4.2_09\jre\bin\java.dll是否存在,如果存在這c:\j2sdk1.4.2_09\jre作為jre路徑.如果不存在調用GetPublicJREHome查HKEY_LOCAL_MACHINE\Software\JavaSoft\Java Runtime Environment\「當前JRE版本號」\JavaHome的路徑為jre路徑。
然後裝載jvm.cfg文件JRE路徑+\lib+\ARCH(CPU構架)+\jvm.cfgARCH(CPU構架)的判斷是通過java_md.c中GetArch函數判斷的,該函數中windows平台只有兩種情況:WIN64的『ia64』,其他情況都為『i386』。以我的為例:C:\j2sdk1.4.2_09\jre\lib\i386\jvm.cfg.主要的內容如下:
-client KNOWN
-server KNOWN
-hotspot ALIASED_TO -client
-classic WARN
-native ERROR
-green ERROR
在我們的jdk目錄中jre\bin\server和jre\bin\client都有jvm.dll文件存在,而java正是通過jvm.cfg配置文件來管理這些不同版本的jvm.dll的.通過文件我們可以定義目前jdk中支持那些jvm,前面部分(client)是jvm名稱,後面是參數,KNOWN表示jvm存在,ALIASED_TO表示給別的jvm取一個別名,WARN表示不存在時找一個jvm替代,ERROR表示不存在拋出異常.在運行java XXX是,java.exe會通過CheckJvmType來檢查當前的jvm類型,java可以通過兩種參數的方式來指定具體的jvm類型,一種按照jvm.cfg文件中的jvm名稱指定,第二種方法是直接指定,它們執行的方法分別是「java -J」、「java -XXaltjvm=」或「java -J-XXaltjvm=」。如果是第一種參數傳遞方式,CheckJvmType函數會取參數『-J』後面的jvm名稱,然後從已知的jvm配置參數中查找如果找到同名的則去掉該jvm名稱前的『-』直接返回該值;而第二種方法,會直接返回「-XXaltjvm=」或「-J-XXaltjvm=」後面的jvm類型名稱;如果在運行java時未指定上面兩種方法中的任一一種參數,CheckJvmType會取配置文件中第一個配置中的jvm名稱,去掉名稱前面的『-』返回該值。CheckJvmType函數的這個返回值會在下面的函數中匯同jre路徑組合成jvm.dll的絕對路徑。如果沒有指定這會使用jvm.cfg中第一個定義的jvm.可以通過set _JAVA_LAUNCHER_DEBUG=1在控制台上測試.
最後獲得jvm.dll的路徑,JRE路徑+\bin+\jvm類型字元串+\jvm.dll就是jvm的文件路徑了,但是如果在調用java程序時用-XXaltjvm=參數指定的路徑path,就直接用path+\jvm.dll文件做為jvm.dll的文件路徑.
二:裝載jvm.dll
通過第一步已經找到了jvm的路徑,java通過LoadJavaVM來裝入jvm.dll文件.裝入工作很簡單就是調用windows API函數:
LoadLibrary裝載jvm.dll動態連接庫.然後把jvm.dll中的導出函數JNI_CreateJavaVM和JNI_GetDefaultJavaVMInitArgs掛接到InvocationFunctions變數的CreateJavaVM和GetDefaultJavaVMInitArgs函數指針變數上。jvm.dll的裝載工作宣告完成。
三:初始化jvm,獲得本地調用介面,這樣就可以在java中調用jvm的函數了.調用InvocationFunctions->CreateJavaVM也就是jvm中JNI_CreateJavaVM方法獲得JNIEnv結構的實例.
四:運行java程序.
java程序有兩種方式一種是jar包,一種是class. 運行jar,java -jar XXX.jar運行的時候,java.exe調用GetMainClassName函數,該函數先獲得JNIEnv實例然後調用java類java.util.jar.JarFileJNIEnv中方法getManifest()並從返回的Manifest對象中取getAttributes("Main-Class")的值即jar包中文件:META-INF/MANIFEST.MF指定的Main-Class的主類名作為運行的主類。之後main函數會調用java.c中LoadClass方法裝載該主類(使用JNIEnv實例的FindClass)。main函數直接調用java.c中LoadClass方法裝載該類。如果是執行class方法。main函數直接調用java.c中LoadClass方法裝載該類。

然後main函數調用JNIEnv實例的GetStaticMethodID方法查找裝載的class主類中
「public static void main(String[] args)」方法,並判斷該方法是否為public方法,然後調用JNIEnv實例的
CallStaticVoidMethod方法調用該java類的main方法。
另外,虛機團上產品團購,超級便宜

『伍』 android jni c 怎麼調用java中的私有方法

public static String getTime() {
Log.d("CCallJava", "Call From C Java Static Method" +String.valueOf(System.currentTimeMillis()));
return String.valueOf(System.currentTimeMillis());
}

public void sayHello(String msg) {
Log.d("CCallJava", "Call From C Java void Method" +String.valueOf(System.currentTimeMillis()));
}

『陸』 java 通過jni 向 c 傳遞一個 java 對象, c 如何取得這個對象的屬性值

對於java傳遞進來的java對象模型,c要載入java類的原型,根據創建相應的c對象,獲取java對象的方法的id,然後調用java對象的方法。比如有個java類customer對象作為jni參數傳遞到c程序,customer有方法String getName()。
JNIEXPORT jobject JNICALL Java_com_oracle_estt_sc_db_impl_SCQueryODBC__1getCustomer
(JNIEnv *env, jobject, jobject customer){
jmethodID methodId;
//獲得customer對象的句柄
jclass cls_objClass=env->GetObjectClass(customer);
//獲得customer對象中特定方法getName的id
methodId=env->GetMethodID(cls_objClass,"getName","()Ljava/lang/String;");
//調用customer對象的特定方法getName
jstring js_name=(jstring)env->CallObjectMethod(customer,methodId,NULL);
...
}

然後C向java傳遞對象方法如下:
JNIEXPORT jobject JNICALL Java_perfecter_jni_LoadJni_getJavaObj(JNIEnv* env,
jobject obj){
jclass clazz=env->FindClass("perfecter/jni/MyObj");

if(clazz==0)
return 0;

jobject jobj=env->AllocObject(clazz);

jfieldID fieldId=env->GetFieldID(clazz,"name","Ljava/lang/String;");

env->SetObjectField(jobj,fieldId,env->NewStringUTF("wahaha"));

return jobj;
}

java對應的native方法申明public static native MyObj getJavaObj();

『柒』 jni調用 java和c是同個線程嗎

是的,jni調用時, java和c是同個線程。

檢測方法:在java和c中分別把當前線程的id輸出出來查看。

Java獲取線程Id:

Thread.currentThread().getId();

C中獲取線程Id:

GetCurrentThreadId();
熱點內容
python寫入mysql資料庫 發布:2024-11-28 02:52:56 瀏覽:431
網站伺服器太忙怎麼進 發布:2024-11-28 02:47:39 瀏覽:719
linux的系統函數 發布:2024-11-28 02:39:52 瀏覽:295
pm編程卡 發布:2024-11-28 02:39:50 瀏覽:564
convertsql 發布:2024-11-28 02:39:50 瀏覽:387
phpwap源碼 發布:2024-11-28 02:36:46 瀏覽:587
狂牛加密視頻破解 發布:2024-11-28 02:32:54 瀏覽:868
騰訊視頻上傳技巧 發布:2024-11-28 02:28:05 瀏覽:239
2016資料庫系統工程師 發布:2024-11-28 02:22:16 瀏覽:892
壓縮機飛動 發布:2024-11-28 02:00:04 瀏覽:274