回答
看看Java Native Interface: Getting Started。
2.1概述
[...]編寫一個簡單的Java應用程序調用C函數打印 的 「Hello World!」。該過程包含以下步驟:
創建聲明本地方法的類(HelloWorld.java)。使用 javac編譯HelloWorld源文件,產生 文件HelloWorld.class。 javac編譯器隨JDK或Java 2 SDK發行版一起提供。使用
javah -jni
生成包含本機方法 實現的函數原型的C頭文件 (HelloWorld.h
)。 javah工具隨JDK或Java 2 SDK 版本提供。編寫本地 方法的C實現(HelloWorld.c
)。將C實現編譯爲本地庫,從而創建Hello-World.dll
或libHello-World.so
。使用主機環境中可用的C編譯器和鏈接器 。運行HelloWorld程序,使用java運行時解釋器 。類文件(HelloWorld.class
) 和本機庫(HelloWorld.dll
或libHelloWorld.so
)在運行時加載 。本章的其餘部分將詳細說明 中的這些步驟。2.2寫在Java下面的程序編程語言 聲明本地方法
你開始。該程序定義了一個名爲HelloWorld的類,其中包含一個 本地方法print。
class HelloWorld { private native void print(); public static void main(String[] args) { new HelloWorld().print(); } static { System.loadLibrary("HelloWorld"); } }
HelloWorld類定義以print native方法的聲明開始。接下來是一個主要方法, 實例化Hello-World類並調用此實例的打印本地方法 。類定義的最後一部分是一個靜態的 初始化程序,用於加載包含打印本機方法的 實現的本機庫。
本地方法 (如print)的聲明與Java 編程語言中常規方法的聲明之間有兩點區別。本機方法聲明必須包含 本機修飾符。本地修飾符表示此方法是以另一種語言實現的 。此外,原生方法聲明 以分號(語句結束符符號 )結尾,因爲 類本身沒有針對本地方法的實現。我們將在一個單獨的C文件中實現打印方法。
在調用本地方法打印之前,必須加載 實現打印的本地庫。在這種情況下,我們在
HelloWorld
類的靜態初始化程序中加載本地 庫。在 調用HelloWorld
類中的任何方法之前,Java 虛擬機自動運行靜態初始化程序,從而確保在調用打印本機方法之前加載了 本機庫。我們定義一個能夠運行
HelloWorld
類的主要方法。Hello-World.main
調用本地方法打印的方式與調用常規方法的 相同。
System.loadLibrary
需要一個庫名稱,找到一個與該名稱對應的本地庫,並將本地庫加載到 應用程序中。我們將在後面的 書中討論確切的加載過程。現在簡單地記住,爲了使System.loadLibrary("HelloWorld")
成功,我們需要在Win32上創建 本地庫,稱爲HelloWorld.dll
,或者在 Solaris上創建libHelloWorld.so
。2.3編譯HelloWorld類
您已經定義了HelloWorld類後,保存的源代碼在 文件名爲HelloWorld.java。然後用自帶的JDK或Java 2 SDK版本的 javac編譯器編譯源文件:
javac HelloWorld.java
這個命令會生成一個
HelloWorld.class
文件在當前目錄中。2.4創建的本地方法的頭文件
下一步,我們將使用
javah
工具來生成JNI風格的頭文件 實現C中的本地方法時有用,您可以在Hello-World
運行javah
類如下:javah -jni HelloWorld
頭文件的名稱是類名 具有「
.h
」追加到它的結束。上面顯示的命令 會生成一個名爲HelloWorld.h
的文件。我們不會在這裏列出生成的 頭文件。所述 頭文件的最重要的部分是函數原型Java_HelloWorld_print
,這 是C函數實現該方法HelloWorld.print:JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject);
忽略
JNIEXPORT
和JNICALL
宏現在。您可能已注意到 即使本機方法的相應聲明接受 無參數,本機方法的C實現也接受兩個參數 。每種本地方法 實現的第一個參數是一個JNIEnv
接口指針。第二個參數是對HelloWorld
對象本身的引用 (有點像C++中的「this
」 指針)。我們將在本書稍後討論如何使用JNIEnv
接口 指針和jobject
參數,但是這個簡單的 示例忽略了這兩個參數。2.5編寫本地方法實現
通過
javah
產生的JNI風格的頭文件可以幫助你編寫C或本地方法 C++實現。您編寫的函數 必須遵循生成的頭文件中指定的原型。您 可以實現在C文件中HelloWorld.c
的Hello-World.print
方法 如下:#include <jni.h> #include <stdio.h> #include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj) { printf("Hello World!\n"); return; }
這個本地方法的實現很簡單。它使用printf函數來顯示字符串「Hello World!」然後返回。如前所述,兩個參數,
JNIEnv
指針和對象的引用都被忽略。C程序包括三個頭文件:
jni.h
- 該頭文件提供的信息的本機代碼需要 調用JNI函數。在編寫本地方法時,您必須始終在您的C或C++源文件中包含此文件。stdio.h
- 上面的代碼 也包含stdio.h
,因爲它使用printf
函數。HelloWorld.h
- 使用javah
生成的頭文件。它包括用於Java_HelloWorld_print
函數的C/C++原型。 2.6編譯C源代碼,並創建一個本地庫請記住,當你在
HelloWorld.java
文件創建的HelloWorld
類,包括你行的代碼,加載本地 庫到程序:System.loadLibrary("HelloWorld");
現在編寫了所有必需的C代碼 ,您需要編譯
Hello-World.c
並構建此本機 庫。不同的操作系統支持不同的方法來構建本地 庫。在Solaris上,下面的命令來建立所謂libHello-World.so共享庫 :
cc -G -I/java/include -I/java/include/solaris HelloWorld.c -o libHelloWorld.so
-G選項指示C編譯器生成一個共享庫,而不是常規的Solaris 可執行文件。由於本書中頁寬的限制,我們將命令行分成兩行。您需要在一行中鍵入命令 ,或將該命令放在腳本文件中。上
Win32
,將 以下命令生成一個動態鏈接庫(DLL)HelloWorld.dll
使用Microsoft Visual C++編譯:cl -Ic:\java\include -Ic:\java\include\win32 -MD -LD HelloWorld.c -FeHelloWorld.dll
的
-MD
選項確保HelloWorld.dll
與Win32
多線程C庫鏈接。-LD
選項指示C編譯器生成DLL而不是常規的Win32可執行文件。當然,在Solaris和Win32上, 都需要放入包含自己的設備的包含路徑。2.7運行程序
在這一點上,你必須準備好運行程序的兩個組成部分。 類文件(
HelloWorld.class
)調用本地方法,並且 本地庫(Hello-World.dll
)實現本機方法。因爲
HelloWorld
類包含自己的主要方法,您可以按以下運行 Solaris或Win32的程序:java HelloWorld
你應該看到下面的輸出:
Hello World!
這是重要的是要正確設置您的本機庫路徑 以使程序運行。本機庫路徑是當加載 本機庫時Java虛擬機搜索的目錄列表 。如果您沒有本地庫路徑設置 做正確,那麼您將看到類似以下內容的錯誤:
java.lang.UnsatisfiedLinkError: no HelloWorld in library path at java.lang.Runtime.loadLibrary(Runtime.java) at java.lang.System.loadLibrary(System.java) at HelloWorld.main(HelloWorld.java)
確保本機庫駐留在本地庫路徑的目錄之一。 如果您在Solaris系統上運行,則使用環境變量
LD_LIBRARY_PATH
定義本機庫路徑。使 確信它包含包含文件的目錄的名稱。如果libHelloWorld.so
文件是在當前 目錄,你可以發出在標準 殼(SH)或KornShell(KSH)建立正確的LD_LIBRARY_PATH
環境變量以下兩條命令:LD_LIBRARY_PATH=. export LD_LIBRARY_PATH
等效在 的是C shell(csh或tcsh)命令如下:
setenv LD_LIBRARY_PATH .
如果您在Windows 95或 Windows NT的計算機上運行,確保
HelloWorld.dll
是在T他目前在 目錄下,或者在PATH環境下列出的目錄 變量中。在Java 2 SDK中1。2版本中,你也可以指定Java命令行上的本地庫 路徑爲系統屬性如下:
java -Djava.library.path=. HelloWorld
的「
-D
」命令行選項 設置一個Java平臺的系統性能。將java.library.path
屬性設置爲「.
」會指示Java虛擬機在當前目錄中搜索 本機庫。
Mac用戶可以忽略solaris命令。這個博客幫助我完成了這個答案幫助開始的東西:http://nerdposts.blogspot.com/2010/10/jni-mac-os-x-simple-sample.html – cloudsurfin 2015-07-15 01:31:34
在「異國情調」的範疇,見NestedVM,其編譯C到MIPS,並運行Mips JVM中的VM。
您的選項包括:
Java本地接口
見:https://en.wikipedia.org/wiki/Java_Native_Interface
報價:
JNI允許程序員編寫本地方法來處理情況當應用程序不能完全用Java編程語言編寫時,例如當標準Java類庫不支持特定於平臺的功能或程序庫
Java本機訪問
見:https://en.wikipedia.org/wiki/Java_Native_Access
報價:
Java本機Access是一個社區開發的庫,它可以讓Java程序輕鬆訪問本地共享庫,而無需使用Java Nat ive接口。
JNR-FFI
見:https://github.com/jnr/jnr-ffi
報價:
JNR-FFI是加載本地庫一個Java庫,而無需手動編寫JNI代碼,或使用諸如SWIG之類的工具。
所以JNR diff JNA是? – Pacerier 2017-06-17 21:55:32
結帳JNAerator。 https://code.google.com/p/jnaerator/
您需要提供源代碼和預處理器定義等
對於低於
「CL -Ic使兼容64位的DLL刪除 「-MD」 從語句選項:\ java的\包括-Ic:\ java \ include \ win32 -MD -LD HelloWorld.c -FeHelloWorld.dll「
我得到了解決這個問題的方法。您需要確保的是,您正在使用64位C++編譯器編譯代碼,以調用在64位JRE上運行的Java函數。除此之外,我們需要將創建的dll文件的路徑保存在「環境變量」下的「路徑」中。
如果您使用的是Windows和MinGW GCC,你可能需要額外的標誌,如果你在LIB越來越UnsatisfiedLinkError具體方法:
gcc -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I"%JAVA_HOME%"\include -I"%JAVA_HOME%"\include\win32 BestCode.c -shared -o BestCode.dll
首先要確保加載您的本機庫或.dll文件在類路徑通過產權java.library.path
設置路徑
然後使用System.loadLibrary()
Do not use .dll extension at the end.
- 1. 從Java調用C++函數
- 2. 使用JNI從java調用C函數
- 3. 使用jni從c調用java函數
- 4. 使用JNA從C調用Java函數
- 5. 從C++方法調用Java函數
- 6. 從C#.Net調用Java函數
- 7. 如何從java調用C#函數
- 8. 從Java JNI調用C++函數 - Cocos2d-x
- 9. 如何從c調用Java函數
- 10. 無法從java調用C++函數cocos2dx
- 11. 從C#調用c函數#
- 12. 調用C++函數,從C#
- 13. 從C++調用C#函數?
- 14. 從Clojure調用java函數
- 15. 從Haxe調用Java函數
- 16. 從Rhino調用Java函數
- 17. 從Java調用RPG函數
- 18. 從RASCAL調用Java函數
- 19. 從Java調用oracle函數
- 20. 從Java調用Oracle函數
- 21. 從Java調用matlab函數
- 22. 從JavaScript調用Java函數
- 23. 從C調用Delphi函數#
- 24. 從C調用libyahoo2函數#
- 25. 從C調用oracle函數#
- 26. 調用oracle函數從C#
- 27. C++調用從虛函數
- 28. 從Tcl調用C#函數
- 29. 從C++調用Lua函數
- 30. 從C++調用R函數
你可能想看看JNI(Java本地接口)。 – 2011-05-11 11:13:21
我會從這些http://www.google.co.uk/search?q=JNI+tutorial – 2011-05-11 11:14:07
開始。非常感謝。 – Wen 2011-05-11 13:53:09