网上有很多例子,参照着执行有时候相对路径问题经常卡住了,实战了一把通过后,特重新整理一份,供小白参考
首先需要有一个含有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