java 使用jna 调用so,dll 动态库最新

目录

一、Jna是什么?

二、问题整理

1.linux 读取不到so动态库

2.函数名不对出现的异常

3.Java使用JNA调用dll出现 Invalid memory access错误

4.64位调用32位dll找不到问题

5.动态库关联路径不对,导致不执行

6.类型对应不正确也会出现输出值不对

7.文件位置,系统位数都正确,执行报模块找不到

8.结构体类型返回值

9.java.lang.IllegalArgumentException: Unsupported array argument type: class [F

问题原因是 java 调用动态库传递二维数组

10.Fix this error that JNA gives: Structure.getFieldOrder() on class Something returns names ([field1, field2, ...]) which do not match declared field names ([])

总结


前言

java 调用so,dll相关问题整理

jdk 1.8

jna 4.1.0


 








一、Jna是什么?

提到JNA 就不得不提一下JNI(Java Native Interface),有过不同语言间通信开发经历的一般都知道,它允许java和其他语言代码(尤其是C/C++)进行交互,只要遵守约定即可








二、问题整理




1.linux 读取不到so动态库

解决如下:

linux环境下 读取so动态库方式两种方式

1.将so动态库放在 /usr/lib 中

2.将so名称加入前缀 libxxx.so,放在 linux-x86-64


2.函数名不对出现的异常

 

java.lang.UnsatisfiedLinkError: Error looking up function 'Recognition': /tmp/jna-3506402/jna595594145827778689.tmp: undefined symbol: Recognition

 核对函数名,参数等

3.Java使用JNA调用dll出现 Invalid memory access错误

 

想着应该是数据类型转换出现了错误。例如dll方法中出现了int*,我仿着delphi用int去映射。问题就在这里,JNA关于指针映射这块有自己的类型。int*对应的是IntByReference这个类型(其他指针类型转换参照JNA指针映射 )。改正类型后,程序成功运行。

4.64位调用32位dll找不到问题

java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序。
 

安装32位jdk ,jdk-8u301-windows-i586.exe 

 固定目录存放在resource下

linux-64linux-x86-64
win32       win32-x86
win64win32-x86-64

创建win32-x86目录,dll放在其下

5.动态库关联路径不对,导致不执行

放到 C:\Program Files (x86)\Java\jdk1.8.0_301\bin 下正常

6.类型对应不正确也会出现输出值不对



 

uint8_t      byte
uint16_t      short
uint32_t      long/ int

7.文件位置,系统位数都正确,执行报模块找不到

解决方式:看动态库的原语言运行环境是否正确。

8.结构体类型返回值

  •  构造结构体
public interface Test1Library extends Library {

    Test1Library DIAGNOSIS = (Test1Library) Native.loadLibrary("diagnosis_dll",     Test1Library.class);


    DiagnosisResponse.ByValue func_realization(float i1[], int size1);

    class DiagnosisResponse extends Structure{
        
        public float D_I1n;
 
        public float D_I2n;

        public static class ByValue extends DiagnosisResponse implements Structure.ByValue              
       {
            @Override
            protected List getFieldOrder() {
                return Arrays.asList(new String[]{"D_I1n", "D_I2n"});
            }
        }

}
  •  调用 Test1Library.DiagnosisResponse diagnosisResponse = INSTANCE.func_realization(diagnosisRequest.getI1(), diagnosisRequest.getI1Size());

9.java.lang.IllegalArgumentException: Unsupported array argument type: class [F

问题原因是 java 调用动态库传递二维数组

public class ForecasRequest extends Structure {
    public float[] forecast = new float[2];
    public static class ByReference extends ForecasRequest implements Structure.ByReference {}
    public static class ByValue extends ForecasRequest implements Structure.ByValue {}

    @Override
    protected List<String> getFieldOrder() {
        return Arrays.asList(new String[]{"forecast"});
    }
}


通过结构体来传递二维数组

    ForecasRequest[] forecas = (ForecasRequest[]) new ForecasRequest().toArray(3);


        forecas[0].forecast = new float[2]{1,2};
        forecas[1].forecast = new float[2]{2,2};
        forecas[2].forecast = new float[2]{4,2};

10.Fix this error that JNA gives: Structure.getFieldOrder() on class Something returns names ([field1, field2, ...]) which do not match declared field names ([])

解决方式:You need to make your fields public

所有返回字段需要为公共的

总结

后续问题持续整理

ps: 走过路过给个赞奥!!!

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值