public class JNIT { static { System.loadLibrary("JNIT"); } public static native String hello(String msg); public static void main(String[] args) { String str= hello("Hello, c++!" ); System.out.print("java get c++ Str:"+str); } }
/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class JNIT */ #ifndef _Included_JNIT #define _Included_JNIT #ifdef __cplusplus extern "C" { #endif /* * Class: JNIT * Method: hello * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_JNIT_hello (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif
注:
文件中的 Java_JNIT_hello 說明是Java中的JNIT類的hello方法
文件中的 #include<jni.h>等 <> 符號在命令行打包動態庫時會打包失敗 須要改成 「jni.h」java
生成的文件中須要導入的jni.h 和 jni_md.h 在JAVAHOME/jdk/include和 JAVAHOME/jdk/include/win32 目錄下,你能夠選擇直接拷貝或後期配置添加(注意32和64位區分)linux
// dllmain.cpp : 定義 DLL 應用程序的入口點。 // pch.cpp: 與預編譯標頭對應的源文件 #include "JNIT.h" // 當使用預編譯的頭時,須要使用此源文件,編譯才能成功。 #include <iostream> using namespace std; JNIEXPORT jstring JNICALL Java_JNIT_hello (JNIEnv * jEnv, jclass jcls, jstring jstr) { const char *c_str = NULL; char buff[128] = { 0 }; c_str = (jEnv)->GetStringUTFChars(jstr,false); if (c_str == NULL) { printf("out of memory.\n"); } cout << "c++ get Java Str: "<< c_str << endl; // (jEnv)->ReleaseStringUTFChars( jstr, c_str); //printf("c++ get Java Str:%s\n", c_str); return (jEnv)->NewStringUTF("hello java"); }
這裏gcc的環境有32位與64位的區分 否則運行會有錯誤Exception in thread "main" java.lang.UnsatisfiedLinkError: D:\eclipsejee\workspace\JNIT\src\JNIT.dll: Can't load IA 32-bit .dll on a AMD 64-bit platformios
cl -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -LD HelloWorld.c -FeHelloWorld.dll 參數選項說明: -I :和 mac os x 同樣,包含編譯 JNI 必要的頭文件 -LD:標識將指定的文件編譯成動態連接庫 -Fe:指定編譯後生成的動態連接庫的路徑及文件名
(1)新建dll項目c++
(2)將寫好的JNIT.cpp粘貼內容粘貼到 dllMain.cpp 中 這裏能夠對dllMain.cpp 修更名稱,將JNIT.h粘貼進項目目錄。app
(3)右鍵項目》屬性》c/c++》常規》附加包含目錄,將jdk/include和jdk/include/win32添加進去,從而引入jni.h和jni_md.heclipse
(4)去除編譯器默認對pch文件的預編譯,右鍵項目》屬性》c/c++》預編譯頭》預編譯頭》不使用預編譯頭函數
(5)運行項目,會在控制檯輸出dll文件路徑測試
g++ -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -shared -Wl,–kill-at -s -o lib.dll JNIT.cpp 解釋一下: -I(大寫字母I,include的意思)是加入本身的庫,也就是告訴編譯器jni.h的位置。固然不加這個參數也能夠,本身把jni.h和jni_md.h文件複製出來和Test.c放一塊兒,另外include改成」」 -shared表示編譯成.dll庫文件 -s參數能夠大幅減少.dll文件的大小,不加也能夠 -o表示目標文件名,不加也能夠,會有默認名,但要本身改爲java中導入庫的名字,這裏是lib -Wl,–kill-at 防止編譯後的函數名被自動加上@符號,並取消警告。(是小寫字母L,不是數字1)
當你把jni.h 和jni_md.h 粘貼到當前目錄下可使用如下命令
g++ -shared -Wl,-kill-at -s -o lib.dll JNIT.cpp
g++ -s -o JNIT.dll JNIT.cpp
g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -fPIC -shared -o JNIT.so 參數說明: -I: 包含編譯JNI必要的頭文件 -fPIC: 編譯成與位置無關的獨立代碼 -shared:編譯成動態庫 -o: 指定編譯後動態庫生成的路徑和文件名
當你把jni.h 和jni_md.h 粘貼到當前目錄下可使用如下命令
g++ -shared -Wl,-kill-at -s -o lib.dll JNIT.cpp
g++ JNIT.cpp -fPIC -shared -o JNIT.so
java JNIT