jna调用so文件 | 您所在的位置:网站首页 › jna调用so库 › jna调用so文件 |
本文中使用的.dll和.so文件以及Java调用的代码资源: https://download.csdn.net/download/werewolf2017/11014740 1. 编译一个dll文件或so文件 1.1 C++代码 熟悉C/C++的,可以忽略该步骤。由于对C/C++不熟悉,编译dll和so文件只是按部就班,不足之处请指教。 .dll文件是Windows系统的动态链接库文件,.so文件是Linux操作系统的动态链接库文件。 若想直接使用本文中的.dll和.so文件以及Java调用的代码,可以直接从https://download.csdn.net/download/werewolf2017/11014740 中下载。 首先在ide中新建dll项目,此处使用的IDE是Dev-C++。如下图所示。 main.cpp代码如下: #include "main.h" int add(int a,int b){ return a + b; } int factorial(int n){ int i; int r = 1; for(i=1;i main.h的代码如下: #ifndef __MAIN_H__ #define __MAIN_H__ #include /* To use this exported function of dll, include this header * in your project. */ #ifdef BUILD_DLL #define DLL_EXPORT __declspec(dllexport) #else #define DLL_EXPORT __declspec(dllimport) #endif #ifdef __cplusplus extern "C" { #endif int add(int a,int b); int factorial(int n); #ifdef __cplusplus } #endif #endif // __MAIN_H__ 1.2 生成.dll文件 创建好main.cpp和main.h文件后,编译便得到和项目名相同的dll文件。此处项目名为DLLMain,所以编译后得到DLLMain.dll文件。 1.3 生成.so文件 要生成so文件,可以在Linux系统下,执行gcc命令编译得到。命令如下: gcc main.h main.cpp -fPIC -shared -o hello.so 执行命令后,在main.h和main.cpp的同一级目录下,会生成hello.so文件。 Tips :部分博客中提到,使用JNA调用.so文件时,编译出来的so文件名必须lib开头。其实这个是没有这个要求的,具体可往下看。 2. 调用.dll文件和.so文件 2.1 .dll和.so文件的放置路径问题 Windows系统下,被调用的.dll文件放在classpath下即可被加载到。在maven项目中,放在resource目录下即可。如下图所示。 Linux操作系统下,.so文件直接放在classpath下是不能加载成功的。 默认情况下,JNA会从/usr/lib目录下加载.so文件。可通过添加 -Djna.library.path=xxx 来指定JNA加载.so文件的目录路径,其中xxx表示.so文件所在的目录的路径。例如,hello.so所在的目录为/root/sotest/lib,则可指定: -Djna.library.path=/root/sotest/lib 2.2 引入JNA依赖包 此处使用maven: net.java.dev.jna jna 4.2.2 2.3 调用的demo import com.sun.jna.Library; import com.sun.jna.Native; public class TestSo { public interface ITestLib extends Library { // Windows下,libName是.dll文件名 String libName = "DLLMain"; // Linux下,libName是.so的含后缀的文件名。 // 若不加后缀名,则编译.so文件时,文件名必须以lib开头。具体说明可往下看。 // String libName = "hello.so"; ITestLib INSTANCE = (ITestLib) Native.loadLibrary(libName, ITestLib.class); /** * ========= 以下是DLLMain.dll或hello.so中的对应的接口方法 ========= */ /** * 加法 * * @param a * @param b * @return */ public int add(int a, int b); /** * 阶乘 * * @param n * @return */ public int factorial(int n); } public static void main(String[] args) { int c = ITestLib.INSTANCE.add(10, 20); System.out.println("10+20=" + c); int d = ITestLib.INSTANCE.factorial(10); System.out.println("10!=" + d); } } 2.4 运行结果 2.5 关于libName的注意点 Native.loadLibrary(String libName, class interfaceclass)方法中,libName的值有一些注意点,在上面代码中已经有提到,此处再作一次总结。 Windows操作系统下,libName的值是.dll文件去后缀文件名,例如,本文中的DLLMain.dll对应的libName的值是DLLMain。 Linux操作系统下,libName的值是.so文件的完整文件名,例如,本文中的hello.so对应的libName是hello.so。不过,若libName写成带.so后缀的形式,那么,在编译.so文件时,文件名需要以lib开头,即libhello.so,对应的libName是hello(注意,不是libhello)。 |
CopyRight 2018-2019 实验室设备网 版权所有 |