E
Elvandar
Hi all,
I have a problem calling a java method from a DLL written with
JNI...this is the situation: the DLL has some methods to interact with
a RS232 serial port (open it, close it and send a byte array), and when
the port is opened it starts a thread that "listens" to the serial
waiting for incoming data; when some data becomes ready, the thread
calls a java method.
The problem is that the receiving thread can't find the method to call,
so the jmethodID returned from the GetMethodID is always 0...and if I
try to move the GetMethodID instruction in the function
"openSerialPort" it works correctly (the method is found and I can call
it), but if I pass this jmethodID to the thread the entire application
hangs...
Here is the code, hoping someone could help me!!! Sorry for my bad
English
Thanks to all!
=== SerialPort.java ===
package it.ribes.serialDriver;
public class SerialPort {
static {
System.loadLibrary("RS232Driver");
}
public SerialPort() {
}
public native boolean openSerialPort();
public native boolean closeSerialPort();
public native boolean send(byte[] packet, int length);
public boolean openPort() {
return openSerialPort();
}
public boolean closePort() {
return closeSerialPort();
}
public boolean sendPacket(byte[] packet) {
return send(packet,packet.length);
}
public void readPacket(byte[] packet, int dataLength) {
byte[] data = new byte[dataLength];
for(int i = 0; i < dataLength; i++)
data = packet;
this.manager.readPacket(data);
}
}
=== SerialPort.c ===
#include "SerialPort.h"
#include "Windows.h"
#include "Serial.h"
#include <process.h>
#define SERIAL_WAIT_TIMEOUT 250
#define REC_BUFFER_DIM 1024
HANDLE CommHandle = INVALID_HANDLE_VALUE;
HANDLE RecThread = NULL;
BOOL ExitRecThread;
struct event_info_struct
{
JNIEnv *env;
jobject *jobj;
jclass jclazz;
jmethodID send_event;
jmethodID checkMonitorThread;
};
void Receiving_Function (void* param);
JNIEXPORT jboolean JNICALL
Java_it_ribes_serialDriver_SerialPort_openSerialPort (JNIEnv *env,
jobject jobj)
{
CommHandle = SerialInit("COM1",19200);
if(CommHandle == INVALID_HANDLE_VALUE)
return false;
else
{
struct event_info_struct eis;
eis.jclazz = env->GetObjectClass(jobj);
eis.env = env;
eis.jobj = &jobj;
ExitRecThread = FALSE;
RecThread =
(HANDLE)_beginthread(Receiving_Function,1024,(void*)&eis);
return true;
}
}
JNIEXPORT jboolean JNICALL
Java_it_ribes_serialDriver_SerialPort_closeSerialPort (JNIEnv *env,
jobject jobj)
{
ExitRecThread = TRUE;
if(CommHandle == INVALID_HANDLE_VALUE || ClosePort(CommHandle))
{
CommHandle = INVALID_HANDLE_VALUE;
return true;
}
return false;
}
JNIEXPORT jboolean JNICALL Java_it_ribes_serialDriver_SerialPort_send
(JNIEnv *env, jobject jobj, jbyteArray packet, jint length)
{
jbyte* rawJavaData = (jbyte*)malloc(length*sizeof(jbyte));
LPBYTE rawData = (LPBYTE)malloc(length*sizeof(BYTE));
int i = 0, ret;
rawJavaData = env->GetByteArrayElements(packet,NULL);
for(; i < length; i++)
rawData = rawJavaData;
ret = SerialWriteStream(CommHandle,rawData,length);
free(rawData);
free(rawJavaData);
if(ret)
return true;
else
return false;
}
void Receiving_Function (void* param)
{
struct event_info_struct *eis = ( struct event_info_struct * )
param;
LPBYTE RecBuffer = (LPBYTE)malloc(REC_BUFFER_DIM * sizeof(BYTE));
BYTE b;
WORD Dim = 0;
DWORD dwTimeout;
while(!ExitRecThread)
{
dwTimeout = GetTickCount () + SERIAL_WAIT_TIMEOUT;
while (!SerialReadChar (CommHandle, &b))
{
if (GetTickCount () > dwTimeout)
{
if(Dim > 0 && !ExitRecThread)
{
SerialWriteString(CommHandle,"passing data to
java\r\n");
jmethodID mid =
eis->env->GetMethodID(eis->jclazz,"readPacket","([BI)V");
if(mid != 0) // NEVER ENTERS HERE!!!
{
SerialWriteString(CommHandle,"Found!\r\n");
eis->env->CallVoidMethod(*(eis->jobj), mid,
RecBuffer, Dim);
}
else
{
SerialWriteString(CommHandle,"Not found\r\n");
}
Dim = 0;
}
}
}
if(!ExitRecThread)
RecBuffer[Dim++] = b;
}
free(RecBuffer);
_endthread();
}
I have a problem calling a java method from a DLL written with
JNI...this is the situation: the DLL has some methods to interact with
a RS232 serial port (open it, close it and send a byte array), and when
the port is opened it starts a thread that "listens" to the serial
waiting for incoming data; when some data becomes ready, the thread
calls a java method.
The problem is that the receiving thread can't find the method to call,
so the jmethodID returned from the GetMethodID is always 0...and if I
try to move the GetMethodID instruction in the function
"openSerialPort" it works correctly (the method is found and I can call
it), but if I pass this jmethodID to the thread the entire application
hangs...
Here is the code, hoping someone could help me!!! Sorry for my bad
English
Thanks to all!
=== SerialPort.java ===
package it.ribes.serialDriver;
public class SerialPort {
static {
System.loadLibrary("RS232Driver");
}
public SerialPort() {
}
public native boolean openSerialPort();
public native boolean closeSerialPort();
public native boolean send(byte[] packet, int length);
public boolean openPort() {
return openSerialPort();
}
public boolean closePort() {
return closeSerialPort();
}
public boolean sendPacket(byte[] packet) {
return send(packet,packet.length);
}
public void readPacket(byte[] packet, int dataLength) {
byte[] data = new byte[dataLength];
for(int i = 0; i < dataLength; i++)
data = packet;
this.manager.readPacket(data);
}
}
=== SerialPort.c ===
#include "SerialPort.h"
#include "Windows.h"
#include "Serial.h"
#include <process.h>
#define SERIAL_WAIT_TIMEOUT 250
#define REC_BUFFER_DIM 1024
HANDLE CommHandle = INVALID_HANDLE_VALUE;
HANDLE RecThread = NULL;
BOOL ExitRecThread;
struct event_info_struct
{
JNIEnv *env;
jobject *jobj;
jclass jclazz;
jmethodID send_event;
jmethodID checkMonitorThread;
};
void Receiving_Function (void* param);
JNIEXPORT jboolean JNICALL
Java_it_ribes_serialDriver_SerialPort_openSerialPort (JNIEnv *env,
jobject jobj)
{
CommHandle = SerialInit("COM1",19200);
if(CommHandle == INVALID_HANDLE_VALUE)
return false;
else
{
struct event_info_struct eis;
eis.jclazz = env->GetObjectClass(jobj);
eis.env = env;
eis.jobj = &jobj;
ExitRecThread = FALSE;
RecThread =
(HANDLE)_beginthread(Receiving_Function,1024,(void*)&eis);
return true;
}
}
JNIEXPORT jboolean JNICALL
Java_it_ribes_serialDriver_SerialPort_closeSerialPort (JNIEnv *env,
jobject jobj)
{
ExitRecThread = TRUE;
if(CommHandle == INVALID_HANDLE_VALUE || ClosePort(CommHandle))
{
CommHandle = INVALID_HANDLE_VALUE;
return true;
}
return false;
}
JNIEXPORT jboolean JNICALL Java_it_ribes_serialDriver_SerialPort_send
(JNIEnv *env, jobject jobj, jbyteArray packet, jint length)
{
jbyte* rawJavaData = (jbyte*)malloc(length*sizeof(jbyte));
LPBYTE rawData = (LPBYTE)malloc(length*sizeof(BYTE));
int i = 0, ret;
rawJavaData = env->GetByteArrayElements(packet,NULL);
for(; i < length; i++)
rawData = rawJavaData;
ret = SerialWriteStream(CommHandle,rawData,length);
free(rawData);
free(rawJavaData);
if(ret)
return true;
else
return false;
}
void Receiving_Function (void* param)
{
struct event_info_struct *eis = ( struct event_info_struct * )
param;
LPBYTE RecBuffer = (LPBYTE)malloc(REC_BUFFER_DIM * sizeof(BYTE));
BYTE b;
WORD Dim = 0;
DWORD dwTimeout;
while(!ExitRecThread)
{
dwTimeout = GetTickCount () + SERIAL_WAIT_TIMEOUT;
while (!SerialReadChar (CommHandle, &b))
{
if (GetTickCount () > dwTimeout)
{
if(Dim > 0 && !ExitRecThread)
{
SerialWriteString(CommHandle,"passing data to
java\r\n");
jmethodID mid =
eis->env->GetMethodID(eis->jclazz,"readPacket","([BI)V");
if(mid != 0) // NEVER ENTERS HERE!!!
{
SerialWriteString(CommHandle,"Found!\r\n");
eis->env->CallVoidMethod(*(eis->jobj), mid,
RecBuffer, Dim);
}
else
{
SerialWriteString(CommHandle,"Not found\r\n");
}
Dim = 0;
}
}
}
if(!ExitRecThread)
RecBuffer[Dim++] = b;
}
free(RecBuffer);
_endthread();
}