java jna调用so文件_JNA调用.dll或.so动态链接库文件

本文介绍了如何使用Java JNA调用.dll(Windows)和.so(Linux)文件。提供了C++代码示例,详细解释了编译动态链接库的步骤,并展示了在不同操作系统下加载库文件的方法,包括设置JNA加载路径和修改libName的注意事项。
摘要由CSDN通过智能技术生成

本文中使用的.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++。如下图所示。

480e171a04b92959d0c4442511449a0e.png

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目录下即可。如下图所示。

03ba98d69393dad563788e1a154d5d0e.png

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 运行结果

24fa8af95d07eb0d11a377db4c5b0a54.png

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)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值