原理就不细说了,其实就是写个库给Java调,可以百度一下Java JNI,下面是HelloWorld代码测试
package com.my.study.cpp_jni;
/**
* 测试Java调用C++库
* 使用命令javac -h . NativeTest.java自动生成C头文件
* 到jdk中的include\win32下单jni.h和jni_md.h头文件拷过来
* 实现cpp文件
* 编译
* 导入
* 配置cpp库文件
* System.load("D:/xxx/java/com/my/study/cpp_jni/MyLibrary.so");
*
*/
public class NativeTest {
static {
/*
// 设置java.library.path路径
System.setProperty("java.library.path", "/path/to/library");
// 通过System.loadLibrary()加载库文件
System.loadLibrary("mylibrary");
*/
System.load("D:/xxx/java/com/my/study/cpp_jni/MyLibrary.dll");
}
private native void print();
public static void main(String[] args) {
new NativeTest().print();
}
}
用命令javac -h . NativeTest.java自动生成C头文件
javac -h . NativeTest.java
生成文件com_my_study_cpp_jni_NativeTest.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class com_my_study_cpp_jni_NativeTest */
#ifndef _Included_com_my_study_cpp_jni_NativeTest
#define _Included_com_my_study_cpp_jni_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_my_study_cpp_jni_NativeTest
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_my_study_cpp_jni_NativeTest_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
修改com_my_study_cpp_jni_NativeTest.h文件的#include

#include
#include "com_my_study_cpp_jni_NativeTest.h"
using namespace std;
JNIEXPORT void JNICALL Java_com_my_study_cpp_jni_NativeTest_print(JNIEnv *, jobject) {
cout << "Hello Word JNI" << endl;
}
编译C源代码并创建本地库
// 编译C语言库
// gcc -ID:\xxx\Java\Java8\jdk\include\ -ID:\xxx\Java\Java8\jdk\include\win32\ NativeTest.c -shared -o MyLibrary.so
// 编译C++库
// g++ -ID:\xxx\Java\Java8\jdk\include\ -ID:\xxx\Java\Java8\jdk\include\win32\ NativeTest.cpp -shared -o MyLibrary.so
// gcc -I 表示将后面的目录表示为第n个头文件的目录

这里不如直接把vs装上测试,因为那个无法找到库文件的问题我弄了几个小时,这里不如直接装上vs,装好vs后几分钟就生成好dll库了
我这里使用VS2022生成动态链接库,装好创建一个C++项目
这里是刚才根据对应头文件和cpp实现文件创建的文件结构,文件都是上面的文件,把文件放到对应位置就行了

对了这里的pch.h预编译头去掉一下,因为用不到,要不然一直报错

使用vs生成动态链接库,把生成的代码放到D盘根目录,方便测试,修改一下Java测试代码,这里可以看到我这里使用g++指令生成的动态链接库比使用vs生成的动态链接库小,说明使用指令生成的动态链接库还差了什么东西在里面,我对C++也不熟悉,所以这里使用vs生成了

/**
* 测试Java调用C++库
* 使用命令javac -h . NativeTest.java自动生成C头文件
* 到jdk中的include\win32下单jni.h和jni_md.h头文件拷过来
* 实现cpp文件
* 编译
* 导入
* 配置cpp库文件
* System.load("D:/xxx/java/com/my/study/cpp_jni/_013_Cpp_VS_Dynamic_Link_Lib.dll");
* System.loadLibrary("_013_Cpp_VS_Dynamic_Link_Lib");//不加dll
* Can't load IA 32-bit .dll on a AMD 64-bit platform:需要下载64位cpp编译器,不同cpu编译器不同
*/
public class NativeTest {
static {
System.load("D:/_013_Cpp_VS_Dynamic_Link_Lib.dll");
}
private native void print();
public static void main(String[] args) {
new NativeTest().print();
}
}
idea运行测试:

这里可以看到运行了C++编译打印的字符串Hello World JNI,成功了,撒花