EXCEPTION_ACCESS_VIOLATION (0xc0000005) 来自 JNI 的 JVM?

发布于 2024-12-08 17:10:51 字数 2237 浏览 0 评论 0原文

我在 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);

(当然在这种情况下数据永远不会返回......)。我在这里做错了什么?

I wrote some native methods in a vc++ with JNI to be accessed from java. Two of my three methods work perfectly fine with no issues. My last method, however, has been causing the following error message when i call it during runtime:

# 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

Here is my native method's code (in 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;
}

My Java code looks like this (abridged of course):

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

Like I said before, the other methods (i.e. connect and senddata) work fine and but I get the error from the receiveData method. After some debugging I discovered that the error goes away when I comment out the line:

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

in my native code (of course the data never gets returned in this case...). What am I doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浪漫之都 2024-12-15 17:10:51

你是不是缺少类似的东西
ReturnPacketBuffer = (*env)->NewCharArray(env, 64);

Aren't you missing something like
ReturnPacketBuffer = (*env)->NewCharArray(env, 64);

倾城月光淡如水﹏ 2024-12-15 17:10:51

异常代码针对未初始化的内存访问,作为提示,请查找索引越界。

The exception code is for uninitalized memory access, as a hint, look for indexing out of bounds.

宣告ˉ结束 2024-12-15 17:10:51
for(int i=0;i<64;i++) 
{
    temp[i] = jchar(InputPacketBuffer[i+1]);
}

temp 可以容纳 65 个 jchar 类型的元素。它们最初持有一些垃圾值。通过上面的循环,您尝试填充从 063 的元素。最后一个元素未填充,并保留其最初具有的垃圾值。

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

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

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

temp can hold 65 elements of type jchar. They initially hold some garbage values. With the above loop, you try to fill from 0 to 63 elements. The last element is left unfilled and is left with the garbage value which it had initially.

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

Probably, the above statement is working on value at the 64th index of temp and is failing because of garbage in it. Try giving an index less than 64, it works, IMO. Or fill the 64th index also with a valid value by incrementing the for loop iteration to one another iteration.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文