導航:首頁 > 編程語言 > java調用cjni

java調用cjni

發布時間:2024-08-07 15:32:52

A. jni調用 java和c是同個線程嗎

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

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

Java獲取線程Id:

Thread.currentThread().getId();

C中獲取線程Id:

GetCurrentThreadId();

B. Java如何調用C語言代碼

Java Native Interface(JNI)是Java語言的本地編程介面,是J2SDK的一部分。在java程序中,我們可以通過JNI實現一些用java語言不便實現的功能。通常有以下幾種情況我們需要使用JNI來實現。 標準的java類庫沒有提供你的應用程序所需要的功能,通常這些功能是平台相關的 你希望使用一些已經有的類庫或者應用程序,而他們並非用java語言編寫的 程序的某些部分對速度要求比較苛刻,你選擇用匯編或者c語言來實現並在java語言中調用他們 下面我們開始編寫HelloWorld程序,由於涉及到要編寫c/c++代碼因此我們會在開發中使用Microsoft VC++工具。編寫java代碼,我們在硬碟上建立一個hello目錄作為我們的工作目錄,首先我們需要編寫自己的java代碼,在java代碼中我們會聲明native方法,代碼非常簡單。如下所示 class HelloWorld { public native void displayHelloWorld(); static { System.loadLibrary("hello"); } public static void main(String[] args) { new HelloWorld().displayHelloWorld(); } } 注意我們的displayHelloWorld()方法的聲明,它有一個關鍵字native,表明這個方法使用java以外的語言實現。方法不包括實現,因為我們要用c/c++語言實現它。注意System.loadLibrary("hello")這句代碼,它是在靜態初始化塊中定義的,系統用來裝載hello共享庫,這就是我們在後面生成的hello.dll(如果在其他的操作系統可能是其他的形式,比如hello.so) 編譯java代碼 javac HelloWorld.java 生成HelloWorld.class文件 創建.h文件 這一步中我們要使用javah命令生成.h文件,這個文件要在後面的c/c++代碼中用到,我們運行 javah HelloWorld。這樣我們可以看到在相同目錄下生成了一個HelloWorld.h文件,文件內容如下 在此我們不對他進行太多的解釋。 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: HelloWorld * Method: displayHelloWorld * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 編寫本地實現代碼 在這部分我們要用C/C++語言實現java中定義的方法,我們在VC++中新建一個Project,然後創建一個HelloWorldImp.cpp文件,內容如下 #include <jni.h> #include "HelloWorld.h" #include <stdio.h> JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) { printf("Hello world!\n"); return; } 注意我們這里include了 jni.h和剛才得到的HelloWorld.h文件。因此你要在VC++裡面設置好,jni.h在JAVA_HOME/include裡面。編譯通過後再生成hello.dll文件。 運行java程序 把上面生成的hello.dll文件復制到我們的工作目錄,這時候我們的目錄中包括HelloWorld.java,HelloWorld.class和hello.dll文件。運行java HelloWorld命令,則可在控制台看到Hello world| 的輸出了。運行VC++; 文件---新建---選「win32 console application」(控制台程序)---在右方設置好路徑並輸入工程名---確定 接下來的幾個提示框點確定就行了,那是提示是否要用VC++提供的框架之類的 在左邊的工作空間中選「FILEVIEW」標簽項,點開「+」號,右鍵點擊「SOURCE FILES」,選「添加文件到目錄」,此即添加你要建立的C++源程序文件,會提示你沒有文件,是否添加,你點是,輸入文件名保存就OK了 然後SOURCE FILES下就出現了你剛才建立的*.CPP文件,雙擊,輸入代碼. 以下就是點」組建」菜單中的」編譯」、」組建」等命令進行調試了。 相信你會了。 http://hi..com/%C7%E9%D4%B5and%D3%D1%D2%EA/blog/item/34084645e8560f23cefca3b7.html

C. Java核心技術第八版(2)中Java調用C函數JNI的例子,通過javah生成C語言頭文件中有一段代碼意思不懂

JNICALL表示調用約定,相當於C++的stdcall,說明調用的是本地方法
JNIEXPORT表示激亂函數的鏈接方式,當程序執行的時候明明檔從本地庫槐罩文件中找函數

D. 什麼樣的技術能讓java調用c語言的代碼

com組件

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方法。
另外,虛機團上產品團購,超級便宜

F. 怎樣用 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"。

閱讀全文

與java調用cjni相關的資料

熱點內容
什麼演算法治宣傳 瀏覽:12
哪個app可以測溫槍 瀏覽:17
macmongodbphp 瀏覽:322
php寫游戲伺服器 瀏覽:871
對立陣營插旗命令 瀏覽:361
java實現帕斯卡三角形演算法 瀏覽:314
linux文件名限制 瀏覽:700
金稅三期代理伺服器地址是什麼意思 瀏覽:429
多自變數擬合Python 瀏覽:452
文件夾加密總是失敗 瀏覽:510
androiddexpathlist 瀏覽:624
要卸載己加密的文件怎麼辦 瀏覽:158
ping伺服器ip地址失敗 瀏覽:136
成都黑馬程序員 瀏覽:637
成考app哪個好 瀏覽:702
linux當前線程id 瀏覽:342
哪個app支持掃花唄 瀏覽:838
著色器編譯程序 瀏覽:583
怎樣看app所屬文件夾 瀏覽:543
如何把網頁轉化為pdf 瀏覽:719