一、创建C++动态库
1.创建一个c++项目
2.创建一个头文件<MyClass.h>
MyClass.h代码:
#pragma once
#define C_API extern "C"
#ifdef _WIN32
#define DLL_API __declspec(dllexport)
#else
#define DLL_API ""
#endif
class MyClass {
public:
MyClass(int value);
int getValue();
void setValue(int value);
private:
int value;
};
// 暴露 C 风格接口
C_API{
DLL_API MyClass* createMyClass(int value);
DLL_API void deleteMyClass(MyClass* obj);
DLL_API int getValue(MyClass* obj);
DLL_API void setValue(MyClass* obj, int value);
}
如果不创建c++对象可以直接写cpp文件,比如:
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) int Add(int a, int b)
{
return a + b;
}
extern "C" __declspec(dllexport) void sayHello()
{
cout << "Hello World" << endl;
}
3.创建资源文件<MyClass.cpp>
(资源文件用来实现头文件里定义的函数)
MyClass.cpp代码:
//#include "pch.h"
#include "MyClass.h"
MyClass::MyClass(int value) : value(value) {}
int MyClass::getValue() {
return value;
}
void MyClass::setValue(int value) {
this->value = value;
}
// C 风格接口实现
extern "C" {
MyClass* createMyClass(int value) {
return new MyClass(value);
}
void deleteMyClass(MyClass* obj) {
delete obj;
}
int getValue(MyClass* obj) {
return obj->getValue();
}
void setValue(MyClass* obj, int value) {
obj->setValue(value);
}
}
4.生成动态库
1.选中C++项目鼠标右键
2.点击《生成》
这里选择生成对应的动态库
在C++项目根目录下有Debug或Release文件夹,生成的动态库就在这个文件夹中。windows只能生成dll动态库,so动态库需要在linux系统运行生成。
二、JNA调用C++接口
1.创建一个Java项目,并添加jna的依赖
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.10.0</version>
</dependency>
2.JNA加载动态库
先创建一个Java文件声明c++接口
package org.jni;
import com.sun.jna.Library;
import com.sun.jna.Pointer;
public interface LibraryAction extends Library {
//不同的c++接口在java里可以写到一个类里面
int Add(int a, int b);
void sayHello();
//C++对象的方法
Pointer createMyClass(int value); // 返回对象指针
void deleteMyClass(Pointer obj); // 释放对象
int getValue(Pointer obj); // 调用对象方法
void setValue(Pointer obj, int value); // 调用对象方法
}
加载C++动态库
package org.jni;
import com.sun.jna.Native;
public class CLibraryAction {
static LibraryAction load;
static {
if(load == null) {
synchronized (LibraryAdd.class) {
System.out.println("开始加载");
load = Native.load("TestLib.dll动态库的路径", LibraryAction.class);
System.out.println("property = " + property);
}
}
}
public static int printLog(){
load.sayHello();
return load.Add(1, 2);
}
}
3.测试C++接口
public static void main(String[] args) {
int i = CLibraryAction.printLog();
System.out.println("i = " + i);
Pointer myClass = CLibraryAction.load.createMyClass(10);
// 调用对象方法
int value = CLibraryAction.load.getValue(myClass);
System.out.println("Initial value: " + value);
// 修改对象属性
CLibraryAction.load.setValue(myClass, 20);
value = CLibraryAction.load.getValue(myClass);
System.out.println("Updated value: " + value);
// 释放对象
CLibraryAction.load.deleteMyClass(myClass);
}
测试结果