Reputation: 1142
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?
Upvotes: 3
Views: 8858
Reputation: 34625
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.
Upvotes: 1
Reputation: 4974
The exception code is for uninitalized memory access, as a hint, look for indexing out of bounds.
Upvotes: 2
Reputation: 745
Aren't you missing something like
ReturnPacketBuffer = (*env)->NewCharArray(env, 64);
Upvotes: 2