網上有很多例子,參照着執行有時候相對路徑問題經常卡住了,實戰了一把通過後,特重新整理一份,供小白參考
首先需要有一個含有native方法的java類
vi /Users/mac/work/git/javademo/src/main/java/com/alioo/jni/JniDemo.java
package com.alioo.jni;
public class JniDemo {
static {
//System.setProperty("jna.library.path", "/Users/mac/work/git/javademo/target/classes/");
//System.loadLibrary("libHello.dylib");
//System.loadLibrary("Hello");
System.load("/Users/mac/work/git/javademo/target/classes/libHello.dylib");
}
public native void printHello();
public static void main(String[] args) {
new JniDemo().printHello();
}
}
編譯後對應的class文件如下
/Users/mac/work/git/javademo/target/classes/com/alioo/jni/JniDemo.class
通過javah命令來生成c++的.h文件
cd /Users/mac/work/git/javademo/target/classes
javah -jni com.alioo.jni.JniDemo
正常情況下可以生成如下文件com_alioo_jni_JniDemo.h
more /Users/mac/work/git/javademo/target/classes/com_alioo_jni_JniDemo.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_alioo_jni_JniDemo */
#ifndef _Included_com_alioo_jni_JniDemo
#define _Included_com_alioo_jni_JniDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_alioo_jni_JniDemo
* Method: printHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_alioo_jni_JniDemo_printHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
手寫c++實現類com_alioo_jni_JniDemo.cpp
備註:實現類com_alioo_jni_JniDemo.cpp跟com_alioo_jni_JniDemo.h在同一個目錄裏
vi /Users/mac/work/git/javademo/target/classes/com_alioo_jni_JniDemo.cpp
#include <iostream>
#include "com_alioo_jni_JniDemo.h"
JNIEXPORT void JNICALL Java_com_alioo_jni_JniDemo_printHello
(JNIEnv *, jobject)
{
printf("Hello, Java world!\n");
return ;
}
int main(){
return 1;
}
生成動態鏈接庫
備註:這一步你不能直接複製,需要改成你電腦中實際的jdk的路徑
cd /Users/mac/work/git/javademo/target/classes
g++ -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/ com_alioo_jni_JniDemo.cpp -o libHello.dylib
可能遇到的錯誤及解決辦法
‘jni.h’ file not found
$ g++ -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/ com_alioo_jni_JniDemo.cpp -o libHello.dylib
com_alioo_jni_JniDemo.cpp:1:10: fatal error: 'jni.h' file not found
#include "jni.h"
^~~~~~~
1 error generated.
解決辦法
$ sudo cp /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/darwin/jni_md.h /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/
可以看到生成了libHello.dylib
$ ll /Users/mac/work/git/javademo/target/classes
total 56
drwxr-xr-x 9 mac staff 288 Nov 4 10:55 .
drwxr-xr-x 13 mac staff 416 Oct 14 20:00 ..
-rw-r--r-- 1 mac staff 658 Oct 14 20:02 A.class
drwxr-xr-x 3 mac staff 96 Oct 14 16:19 META-INF
drwxr-xr-x 3 mac staff 96 Oct 14 16:49 com
-rw-r--r-- 1 mac staff 181 Nov 4 10:46 com_alioo_jni_JniDemo.cpp
-rw-r--r-- 1 mac staff 442 Nov 4 10:42 com_alioo_jni_JniDemo.h
drwxr-xr-x 3 mac staff 96 Oct 14 16:49 java2
-rwxr-xr-x 1 mac staff 12564 Nov 4 10:55 libHello.dylib
測試一把
$ pwd
/Users/mac/work/git/javademo/target/classes
$ java com.alioo.jni.JniDemo
Hello, Java world!
擴展
當然了,也可以用g++編譯成可執行程序,直接執行,但是這個已經與本文主題無關了,有興趣的也可以試試
cd /Users/mac/work/git/javademo/target/classes
g++ --std=c++11 com_alioo_jni_JniDemo.cpp -I /Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/include/
上述命令如果沒有報錯的情況下會在當前目錄中生成一個可執行程序a.out
./a.out
$ echo $?
1