Problems calling a third-party DLL using a thread

R

Robert Birn

Hello,

I'm using a third-party DLL to control an I/O-Interface via USB.
My Java-program uses JNI to call a native DLL which calls the
functions in the third-party DLL.
Everything works fine when I'm calling the native methods in the
main() function.
But if I invoke the native methods in a Java-Thread, everything also
works but I get the following Windows-Message when the application
_exits_:
JAVAW caused an error in module KERNEL32.DLL...

Here are some Code-Snipplets:
/** the "fine" solution **/
public class Test01 {
public static void main(String[] args) {
JNIinterface jniIF = new JNIinterface();
jniIF.openDevice(0);
jniIF.setAllDigital();
jniIF.closeDevice();
}
}

/** the "bad" solution **/
public class Test02 {
public static void main(String[] args) {
Test02Thread t = new Test02Thread();
t.start();
}
}
public class Test01Thread extends Thread {
public void run() {
JNIinterface jniIF = new JNIinterface();
jniIF.openDevice(0);
jniIF.setAllDigital();
jniIF.closeDevice();
}
}

/** the JNI interface **/
class JNIinterface {
static {
System.loadLibrary("JNIinterface");
}
private native int callOpenDevice(int _cardAddress);
private native void callCloseDevice();
private native void callSetAllDigital();

public int openDevice(int _cardAdress) {
return callOpenDevice(_cardAdress);
}
public void closeDevice() {
callCloseDevice();
}
public void setAllDigital() {
callSetAllDigital();
}
}

Where is my fault?

Regards

Robert
 
G

Gordon Beaton

But if I invoke the native methods in a Java-Thread, everything also
works but I get the following Windows-Message when the application
_exits_:
JAVAW caused an error in module KERNEL32.DLL...

The error is almost certainly in the native code itself. You can't
cause that kind of error in Java (alone), and there is nothing
inherently different about using native methods from threaded code.

/gordon
 
I

Ike

Hmmm, maybe you are using the Mivrosoft VM by chance? If so, that doesnt
support JNI(!), but rather a microsoft-specific standrard called RNI....Make
sure you are using the Sun VM. -Ike
 
R

Robert Birn

Hello,

I found the following solution:
Using explicit linking instead of implicit linking!
First I tried to use the third-party DLL by including the provided C++
header file, but I think there's a problem when the third-party
library is loaded (better: when the "main" thead loads the native
DLL!)
Now I create a method which loads the library (via LoadLibray(..)) and
fetches all function pointers in the library (via GetProcAddress(..)).
At the end, I release all resources (FreeLibrary(..)). Thats all!
Here are some code snipplets:
/** THE SOLUTION **/
#include "JNIinterface.h"
#include <jni.h>
#include <windows.h>

typedef long (CALLBACK* LPFNDLLOpenDevice)(long);
typedef void (CALLBACK* LPFNDLLCloseDevice)();

HMODULE hDLL = NULL;
LPFNDLLOpenDevice OpenDevice = NULL;
LPFNDLLCloseDevice CloseDevice = NULL;

/*
* Class: JNIinterface
* Method: callOpenDevice
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_JNIinterface_callOpenDevice
(JNIEnv *, jobject, jint _id)
{
hDLL = LoadLibrary("3RD_PARTY.dll");
if (hDLL != NULL) {
OpenDevice = (LPFNDLLOpenDevice)GetProcAddress(hDLL, OpenDevice");
CloseDevice = (LPFNDLLCloseDevice)GetProcAddress(hDLL,
"CloseDevice");
if (!OpenDevice || !CloseDevice)
{
FreeLibrary(hDLL);
hDLL = NULL;
return ERROR_GETPROCADDRESS
} else {
OpenDevice(_id);
return SUCCESS;
}
} else {
return ERROR_LOADLIBRARY;
}
}
/*
* Class: JNIinterface
* Method: callCloseDevice
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_JNIinterface_callCloseDevice
(JNIEnv *, jobject)
{
CloseDevice();
FreeLibrary(hDLL);
hDLL = NULL;
return;
}

Thank you for all comments on this topic!

Regards

Robert


Hello,

I'm using a third-party DLL to control an I/O-Interface via USB.
My Java-program uses JNI to call a native DLL which calls the
functions in the third-party DLL.
Everything works fine when I'm calling the native methods in the
main() function.
But if I invoke the native methods in a Java-Thread, everything also
works but I get the following Windows-Message when the application
_exits_:
JAVAW caused an error in module KERNEL32.DLL...

Here are some Code-Snipplets:
/** the "fine" solution **/
public class Test01 {
public static void main(String[] args) {
JNIinterface jniIF = new JNIinterface();
jniIF.openDevice(0);
jniIF.setAllDigital();
jniIF.closeDevice();
}
}

/** the "bad" solution **/
public class Test02 {
public static void main(String[] args) {
Test02Thread t = new Test02Thread();
t.start();
}
}
public class Test01Thread extends Thread {
public void run() {
JNIinterface jniIF = new JNIinterface();
jniIF.openDevice(0);
jniIF.setAllDigital();
jniIF.closeDevice();
}
}

/** the JNI interface **/
class JNIinterface {
static {
System.loadLibrary("JNIinterface");
}
private native int callOpenDevice(int _cardAddress);
private native void callCloseDevice();
private native void callSetAllDigital();

public int openDevice(int _cardAdress) {
return callOpenDevice(_cardAdress);
}
public void closeDevice() {
callCloseDevice();
}
public void setAllDigital() {
callSetAllDigital();
}
}

Where is my fault?

Regards

Robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top