EXCEPTION_ACCESS_VIOLATION (0xc0000005) 来自 JNI 的 JVM?
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你是不是缺少类似的东西
ReturnPacketBuffer = (*env)->NewCharArray(env, 64);
Aren't you missing something like
ReturnPacketBuffer = (*env)->NewCharArray(env, 64);
异常代码针对未初始化的内存访问,作为提示,请查找索引越界。
The exception code is for uninitalized memory access, as a hint, look for indexing out of bounds.
temp
可以容纳 65 个jchar
类型的元素。它们最初持有一些垃圾值。通过上面的循环,您尝试填充从 0 到 63 的元素。最后一个元素未填充,并保留其最初具有的垃圾值。上面的语句可能正在处理
temp
第 64 个索引处的值,但由于其中存在垃圾而失败。尝试给出一个小于 64 的索引,它有效,IMO。或者通过将 for 循环迭代递增到另一迭代,也用有效值填充第 64 个索引。temp
can hold 65 elements of typejchar
. 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.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.