Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >线程“主”java.lang.Error中的JNA异常:无效内存访问(未知源)

线程“主”java.lang.Error中的JNA异常:无效内存访问(未知源)
EN

Stack Overflow用户
提问于 2016-06-27 07:33:40
回答 1查看 10.5K关注 0票数 2

我使用JNA4.0.0从Java访问一些DLL函数,这个DLL本机函数声明如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int ApplicationInit(HANDLE hEMV, TLV *tlv_Appl, TLV *tlv_AIP);

输入参数的类型描述如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* Opaque structure */
typedef void *HANDLE;

typedef struct
{
    unsigned char *_lenptr;     /* pointer to 'len' field (Private member) */
    unsigned int _len;          /* 'outer' length, specified by user (Private member) */
    unsigned short _offset;
    unsigned short len;         /* number of bytes (Public member) */

    unsigned long tag;          /* Tag tag  (Public member) */
    unsigned char *val;         /* byte string  (Public member) */
    unsigned char _tagptr[256]; /* Container for TLV data (Private member) */
} TLV;

因此,我在库接口中声明了如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static class HANDLE extends PointerType {
        public HANDLE(Pointer address) {
            super(address);
        }
        public EMV_HANDLE() {
            super();
        }
    }

public class TLV extends Structure {
    /**
     * pointer to 'len' field (Private member)<br>
     * C type : unsigned char*
     */
    public Pointer _lenptr;
    /** 'outer' length, specified by user (Private member) */
    public int _len;
    public short _offset;
    /** number of bytes (Public member) */
    public short len;
    /** Tag tag  (Public member) */
    public NativeLong tag;
    /**
     * byte string  (Public member)<br>
     * C type : unsigned char*
     */
    public Pointer val;
    /**
     * Container for TLV data (Private member)<br>
     * C type : unsigned char[256]
     */
    public byte[] _tagptr = new byte[256];
    public TLV() {
        super();
    }
    protected List<? > getFieldOrder() {
        return Arrays.asList("_lenptr", "_len", "_offset", "len", "tag", "val", "_tagptr");
    }
    /**
     * @param _lenptr pointer to 'len' field (Private member)<br>
     * C type : unsigned char*<br>
     * @param _len 'outer' length, specified by user (Private member)<br>
     * @param len number of bytes (Public member)<br>
     * @param tag Tag tag  (Public member)<br>
     * @param val byte string  (Public member)<br>
     * C type : unsigned char*<br>
     * @param _tagptr Container for TLV data (Private member)<br>
     * C type : unsigned char[256]
     */
    public TLV(Pointer _lenptr, int _len, short _offset, short len, NativeLong tag, Pointer val, byte _tagptr[]) {
        super();
        this._lenptr = _lenptr;
        this._len = _len;
        this._offset = _offset;
        this.len = len;
        this.tag = tag;
        this.val = val;
        if ((_tagptr.length != this._tagptr.length)) 
            throw new IllegalArgumentException("Wrong array size !");
        this._tagptr = _tagptr;
    }
    public static class ByReference extends TLV implements Structure.ByReference {

    };
    public static class ByValue extends TLV implements Structure.ByValue {

    };
}

int EMV_ApplicationInit(AppdefLibrary_EMVCT.EMV_HANDLE hEMV, TLV.ByReference tlv_Appl, TLV.ByReference tlv_AIP);

然后我用以下的方式来称呼它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
EMV_HANDLE hEMV= new EMV_HANDLE();
TLV.ByReference tlv_Appl=new TLV.ByReference();
TLV.ByReference tlv_AIP=new TLV.ByReference();

System.out.println(AppdefLibrary.INSTANCE.ApplicationInit(hEMV, tlv_Appl, tlv_AIP));

但我得到了以下例外:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Exception in thread "main" java.lang.Error: Invalid memory access
    at com.sun.jna.Native.invokeInt(Native Method)
    at com.sun.jna.Function.invoke(Function.java:383)
    at com.sun.jna.Function.invoke(Function.java:315)
    at com.sun.jna.Library$Handler.invoke(Library.java:212)
    at com.sun.proxy.$Proxy1.ApplicationInit(Unknown Source)
    at test.Test.main(Test.java:192)

请帮助并感谢您的关注!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-28 12:33:21

当您试图访问未正确分配的本机端内存时,会出现无效的内存访问错误。

确切地说,如何分配内存可能会发生几种方式,您必须找到它们来解决您的问题。你必须剥掉几层洋葱才能找到真正的问题。

首先要检查的是JNA类型映射。这里的结构尺寸是出了名的错。但是,您的结构看起来是正确的。

下一个可能的来源是,您没有为结构本身分配本机端内存;这是您选择使用ByReference来处理结构的一个副作用。如果你走这条路,你的开销就会大得多。然而,这都是不必要的;JNA在引擎盖下完成了所有的繁重工作,当您将一个结构作为参数传递给JNA库时,它实际上只将指针发送到本机端.但处理内存分配等。

您应该直接在代码中引用TLV结构。

在图书馆:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int EMV_ApplicationInit(AppdefLibrary_EMVCT.EMV_HANDLE hEMV, TLV tlv_Appl, TLV tlv_AIP);

在您的访问代码中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TLV tlv_Appl=new TLV();
TLV tlv_AIP=new TLV();

System.out.println(AppdefLibrary.INSTANCE.ApplicationInit(hEMV, tlv_Appl, tlv_AIP));

如果修复这个问题并不能解决您的问题,另一种可能是,虽然您已经为Java结构分配了内存,但C方法在内部引用其他内存,API希望您以某种方式初始化您的变量,以便它们指向(分配的)其他内存。未初始化的指针可能是罪魁祸首,特别是如果要作为用户的“输入”,而不是函数将填充的回调。您需要仔细检查API文档,以确定是否存在这种情况,以及是否需要初始化任何指针。

例如,空HANDLE可能不能为该方法所接受;它可能要求您通过其他方法初始化HANDLE (并在稍后发布)。

或者,您可能需要对TLV结构做一些事情来初始化它们的内部指针成员。例如,val字段指向“字节字符串”。API是否期望您已经分配了该内存并提供了您所分配的内存的长度(例如,Pointer val = new Memory(256); tlv_Appl.val = val; tlv_Appl.len = 256;)?_lenptr到底指向什么(注释表示一个int字段,但它是一个char指针,这似乎很奇怪)?

另外,4.0.0是JNA的旧版本;4.2.2是当前版本,除非出于其他原因需要旧版本,否则应该使用它。

另外,JNA已经包含了WinNT.HANDLE的映射,这可能比滚动您自己的映射更好。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38057959

复制
相关文章
Java中常见的异常类型
类格式错误。当Java虚拟机试图从一个文件中读取Java类,而检测到该文件的内容不符合类的有效格式时抛出。
JanYork_简昀
2022/04/02
2.3K0
Java---线程多(工作内存)和内存模型(主内存)分析
转载自 https://www.cnblogs.com/chihirotan/p/6486436.html
allsmallpig
2021/02/25
2K0
JDK源码解析之 java.lang.Error
错误。是所有错误的基类,用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况。
栗筝i
2022/12/01
6280
Java-线程中的异常
给出以下例子,我想问题是线程t1运行期间抛出的异常能够被捕获吗?(这是一个相当好的问题~)
Fisherman渔夫
2020/02/19
1.5K0
cdn节点访问失败,源站测试正常,节点异常?
cdn节点测试访问异常,出现空响应,直接访问源站正常,这里看起来像是节点出现异常。
任雯霄
2020/12/30
3.8K0
java主线程捕获子线程中的异常
如果想要在主线程中捕获子线程的异常,我们需要使用ExecutorService,同时做一些修改。
Java架构师必看
2021/05/14
3K0
java主线程捕获子线程中的异常
java高级用法之:JNA中的Function
在JNA中,为了和native的function进行映射,我们可以有两种mapping方式,第一种是interface mapping,第二种是direct mapping。虽然两种方式不同,但是在具体的方法映射中,我们都需要在JAVA中定义一个和native方法进行映射的方法。
程序那些事
2022/05/17
5710
Java面试系列9
java中的保留字,现在没有在java中使用。 ✎二、必须要知道的运行时异常 ArithmeticException 是出现异常的运算条件时,抛出此异常。 例如,一个整数“除以零”时,抛出此类
Java帮帮
2018/03/19
2K0
winform 多线程中ShowDialog()步骤无效的解决办法
private void Form1_Load(object sender, EventArgs e) { Thread thread = new Thread(remind); thread.IsBackground = true; thread.Start(); } private void remind() { while (true) { string h = "0"; string m = "23";
跟着阿笨一起玩NET
2018/09/19
1.3K0
Java跨语言调用,使用JNA访问Java外部接口
先说JNI(Java Native Interface)吧,有过不同语言间通信经历的一般都知道,它允许Java代码和其他语言(尤其C/C++)写的代码进行交互,只要遵守调用约定即可。首先看下JNI调用C/C++的过程,注意写程序时自下而上,调用时自上而下。
朝雨忆轻尘
2019/06/18
4.6K0
java高级用法之:JNA中的Structure
前面我们讲到了JNA中JAVA代码和native代码的映射,虽然可以通过TypeMapper来将JAVA中的类型和native中的类型进行映射,但是native中的数据类型都是基础类型,如果native中的数据类型是复杂的struct类型该如何进行映射呢?
程序那些事
2022/05/09
1.9K0
java高级用法之:JNA中的Structure
前面我们讲到了JNA中JAVA代码和native代码的映射,虽然可以通过TypeMapper来将JAVA中的类型和native中的类型进行映射,但是native中的数据类型都是基础类型,如果native中的数据类型是复杂的struct类型该如何进行映射呢?
程序那些事
2022/05/17
6640
java高级用法之:JNA中的Function
在JNA中,为了和native的function进行映射,我们可以有两种mapping方式,第一种是interface mapping,第二种是direct mapping。虽然两种方式不同,但是在具体的方法映射中,我们都需要在JAVA中定义一个和native方法进行映射的方法。
程序那些事
2022/05/06
1K0
java高级用法之:JNA中的回调
什么是callback呢?简单点说callback就是回调通知,当我们需要在某个方法完成之后,或者某个事件触发之后,来通知进行某些特定的任务就需要用到callback了。
程序那些事
2022/05/10
1.5K0
java中的异常总结
一般面试中java Exception(runtimeException )是必会被问到的问题
哲洛不闹
2018/09/19
1.4K0
Java多线程中的内存可见性
分为主内存和线程内存,当线程与其他线程共享一个变量时,便会把主内存的变量复制到线程内存中去。当发生对变量的修改时,会同步到主内存,主内存再同步到其他线程内存中去。
zhangheng
2020/04/28
5020
异常、线程
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100192.html原文链接:https://javaforall.cn
全栈程序员站长
2022/06/29
7660
异常、线程
RuntimeException和Exception区别
Java设置了异常,旨在鼓励将方法中可能出现的异常告知给使用此方法的程序员(你和我!)。当然了,这种方法是比较优雅的,让我们确切的知道是在哪里出了错,并提供了异常捕获。本篇文章主要对Java中的异常进行介绍与区分。
全栈程序员站长
2022/09/15
1.1K0
RuntimeException和Exception区别
WPF中UI元素跨线程访问
dotnet中线程资源独占UI元素,不能跨线程访问,可以通过Dispatcher.Invoke的方式调用,但实际处理还是UI线程中,任务量比较大的数据会增加线程的处理压力。 其实还有一种做法,可以通过设置UI元素为只读的方式,跨线程访问。 如BitmapSource跨线程访问,可以调用Freeze设置元素为只读模式。 Aforge.net跨线程传递图像资源,如下:
sofu456
2019/07/09
1.1K0
java高级用法之:JNA中的回调
什么是callback呢?简单点说callback就是回调通知,当我们需要在某个方法完成之后,或者某个事件触发之后,来通知进行某些特定的任务就需要用到callback了。
程序那些事
2022/05/17
8950

相似问题

JNA无效内存访问

13

JNA:无效内存访问

11

JNA:无效内存访问

18

JNA中的无效内存访问

16

映射JNA中的COM接口方法无效内存访问异常

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文