mac环境是:10.15.7 系统,非arm cpu。
jdk 1.8
实验一
原文来自于:Mac下Java JNI 调C
JNI的实现步骤如下:
(1)编写带有native声明的方法的Java类
(2)使用javac命令编译编写的Java类
(3)使用java -jni className 来生成后缀名为.h的头文件
(4)使用其他语言(C、C++)实现本地方法
(5)将本地方法编写的文件生成动态链接库
我们开始来编写一个简单的Java call C
1、编写含有native方法的Java类
public class HelloWorld {
public native void hello();
static {
//设置查找路径为当前项目路径
System.setProperty("java.library.path", ".");
//加载动态库的名称
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().hello();
}
}
2、编译代码
在终端执行 : javac HelloWorld.java
这时会生成HelloWorld.class 文件
3、使用java -jni className 生成后缀名为.h的头文件
在终端执行 : 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: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
4、使用C语言实现本地方法
创建 HelloWorldImpl.c 文件
#include "jni.h"
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_hello(JNIEnv *env,jobject obj){
printf("Hello World!\n");
return;
}
5、将本地方法编写的文件生成动态链接库
使用命令生成动态链接库:
gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include HelloWorldImpl.c -o libhello.jnilib
报错:jni_md.h文件找不到
$ gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include Hello.c -o hello.jnilib
In file included from Hello.c:1:
In file included from ./com_demo_TestLib_JniSo_Hello.h:2:
/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include/jni.h:45:10: fatal error: 'jni_md.h' file not found
#include "jni_md.h"
^~~~~~~~~~
1 error generated.
解决办法:
sudo cp /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include/darwin/jni_md.h /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents
6、last, 执行可执行文件
终端执行 : java HelloWorld
结果:
Hello World!
实验二
1.编写源文件:
package com.demo.TestLib.JniSo;
public class Hello{
static{
System.load("/lib/libHello.so");
}
public native void say();
public native String world(String str);
public static void main(String...args){
Hello hello = new Hello();
hello.say();
System.out.println("java : "+hello.world("hello"));
}
}
2.编译Hello.java - Hello.class
javac com/demo/TestLib/JniSo/Hello.java
3.编译Hello.class 生成 com_jni_Hello.h 的头文件
javah com.demo.TestLib.JniSo.Hello
但是jdk9之后(大概)javah不可用了,应:
4.编写c++/c的业务代码,引用com_jni_Hello.h 的头文件,并实现定义的方法
#include "com_demo_TestLib_JniSo_Hello.h"
#include "string.h"
JNIEXPORT void JNICALL Java_com_demo_TestLib_JniSo_Hello_say(JNIEnv *env, jobject object){
printf("hello world!");
}
JNIEXPORT jstring JNICALL Java_com_demo_TestLib_JniSo_Hello_world(JNIEnv *env, jobject obejct, jstring string){
const char *wd = " world!!";
const char *getstr = (*env)->GetStringUTFChars(env,string, 0);
char *str;
str=strcpy(str,wd);
str=strcpy(str,getstr);
jstring out= (*env)->NewStringUTF(env,str);
return out;
}
5.编译c/c++ 代码生成动态链接库 .jnilib文件
gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include Hello.c -o hello.jnilib
6.运行java程序
$ java com.demo.TestLib.JniSo.Hello
java : hello
hello world!%
参考网址:
1、https://www.cnblogs.com/chenmo-xpw/p/7501325.html
2、https://blog.csdn.net/weixin_38719347/article/details/103001880