好久没有写随笔了,前段时间参与的项目需要使用JAVA调用C++编写的算法库,现在也来分享一下简单的调用教程,Java调用dll/so库一般是有JNI、JNative、JNA。
由于JNI操作比较繁琐,而且也不需要C++调用JAVA的代码,便没有采用;JNative好久不更新了,现在只有32位的支持,于是采用了JNA。
使用VS生成DLL,简单的main示例:
main.cpp
#include "main.h" int add(int a, int b){ return a + b; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } return TRUE; }
main.h
#ifndef __MAIN_H__ #define __MAIN_H__ #include <windows.h> #ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT __declspec(dllimport) #endif //注意头文件一定是要把让外部调用的方法声明出去 #ifdef __cplusplus extern "C" { #endif DLL_EXPORT int add(int a, int b); #ifdef __cplusplus } #endif #endif
这样的话在VS里生成DLL文件,注意:
JDK、系统版本、DLL三者的位数一定要一致!是64位就统一是64位的。
再来编写JAVA代码,在项目中需要引入JNA的jar包,我是在maven中直接引入的,也可以找一下jna的包直接引入也可以。
Maven的引入:
<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId>
</dependency>
引入完成所需要的jar包之后,我们需要在JAVA代码中加载DLL:
public class Test { public interface CLibrary extends Library { CLibrary cLibrary = (CLibrary) Native.loadLibrary("JNATest", CLibrary.class); //声明DLL库里提供的方法 int add(int a ,int b); } public static void main(String[] args) { int res=Test.CLibrary.cLibrary.add(1, 2);
//这样就能成功输出结果 System.out.println(res); } }
注:
JNA在系统平台上会搜索项目当前路径跟系统的path路径查找DLL/SO库文件,在此之前一定保证库文件的依赖是全面的,能正常使用库文件,JNA才能成功调用!
可以使用System.getProperty("java.library.path")查看所要查看的路径。