一、创建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 ""
#endifclass 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);
}
测试结果