繁体   English   中英

来自JNI的EXCEPTION_ACCESS_VIOLATION(0xc0000005)JVM?

[英]EXCEPTION_ACCESS_VIOLATION (0xc0000005) JVM from JNI?

我在vc ++中编写了一些使用JNI的本机方法,可以从java访问。 我的三种方法中的两种方法完美无缺。 但是,我的最后一个方法在运行时调用它时导致以下错误消息:

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x61e06550, pid=3408, tid=4796
#
# JRE version: 7.0-b147
# Java VM: Java HotSpot(TM) Client VM (21.0-b17 mixed mode, sharing windows-x86 )
# Problematic frame:
# V  [jvm.dll+0xa6550]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows

这是我的本机方法的代码(在vc ++中):

JNIEXPORT jcharArray JNICALL Java_jniusb_Main_receiveData (JNIEnv *env, jclass, jchar dataIndex)
{
    DWORD BytesWritten = 0;
    DWORD BytesRead = 0;
    unsigned char OutputPacketBuffer[65];   
    unsigned char InputPacketBuffer[65];    

    static jcharArray ReturnPacketBuffer;
    jchar temp[65];

    //send 'receive data' command to the firmware (OutputPacketBuffer[1])
    WriteFile(WriteHandle, &OutputPacketBuffer, 65, &BytesWritten, 0);
        //retrieve data from firmware
    ReadFile(ReadHandle, &InputPacketBuffer, 65, &BytesRead, 0);        

        for(int i=0;i<64;i++) 
    {
        temp[i] = jchar(InputPacketBuffer[i+1]);
    }

    (*env).SetCharArrayRegion(ReturnPacketBuffer, 0, 64, temp);
    return ReturnPacketBuffer;
}

我的Java代码看起来像这样(当然删节):

public static native char[] receiveData(char dataIndex);

public static void main(String[] args) {
    char vid = 0x4d8;
    char pid = 0x3f;

    //check if read/write handles were retrieved 
    if(connectHid(vid, pid) == true)
    {
        System.out.println("connected!!!");
    }
    else
    {
        System.out.println("not connected...");
    }


    char[] test = new char[64];
    char[] receivetest = new char[64];

    char length = 0x03;
    char dataIndex = 0x81;

    test[0] = 0x80;
    test[1] = 0x80;
    sendData(test, length);
    receivetest = receiveData(dataIndex);

就像我之前说过的,其他方法(即connect和senddata)工作正常,但我从receiveData方法得到错误。 经过一些调试后,我发现当我注释掉这行时错误就消失了:

(*env).SetCharArrayRegion(ReturnPacketBuffer, 0, 64, temp);

在我的本机代码中(当然,在这种情况下数据永远不会返回...)。 我在这做错了什么?

你是不是错过了ReturnPacketBuffer = (*env)->NewCharArray(env, 64);

异常代码用于未经初始化的内存访问,作为提示,查找超出范围的索引。

for(int i=0;i<64;i++) 
{
    temp[i] = jchar(InputPacketBuffer[i+1]);
}

temp可以容纳65个jchar类型的jchar 他们最初持有一些垃圾值。 使用上面的循环,您尝试填充063个元素。 最后一个元素是未填充的,并留有最初的垃圾值。

(*env).SetCharArrayRegion(ReturnPacketBuffer, 0, 64, temp);

可能,上面的语句正在处理temp的第64个索引处的值,并且由于其中的垃圾而失败。 尝试给出小于64的索引,它有效,IMO。 或者通过将for循环迭代增加到另一个迭代来使用有效值填充第64个索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM