Threads not completing on native side
greetings. i'm attempting to send and receive data to and from a usb device. i have all the driver code completed and a C++ class i'm using to represent the device. in my .dll i declare an instance of this object, "MyDevice device." in java when i load the library, device's constructor is called. i can follow C++ and .dll's for the most part but haven't coded them very much. i didn't think device would be instantiated just by loading the .dll but it's ok by me in doing so. the dll has a sendData() method which just calls device.sendData() and that appears to work. device's constructor starts some listener events which get queued in the driver to wait for data from the usb device. i'm sending data to the device that should generate data coming back and my listener's are never completing. it may be that i'm barking up the wrong tree, being a java forum and all, but i have a C++ exe that when run, sends the same data and the listeners do complete. the application calls device.sendData() just like my library. i'm so stuck. i'm not even worried about trying to calling my method on the java side from the library to handle the event because there's no event yet to call my java code. from my description of the problem does anyone know what i might be doing wrong? am i not considering something on the java side or in my dll? if more information is needed to gauge what i'm doing wrong then just say the word. any help would be greatly appreciated. thank you. jerry.
So if I understand you well your have a C++ program that calls your DLL sendData() function and it works because you receive data from usb device.
But your Java program which also calls your DLL sendData() function doesn't work because no data is received from usb device.
Question #1: How do you know you are receiving data in your listeners?
Do you have some printf or logging mechanism?
Question #2: How do you "link" your Java program to your DLL with sendData() function? Do you use a JNI wrapper DLL?
i know i receive data back because i'm using printf's. in answer to question 2, i'm not sure i understand exactly what you're asking. i know you're asking in the right way but i'm getting just a little confused in terminology. my java program contains:
static {
System.loadLibrary("mylibrary.dll");
}
public native int sendData(byte[] packet);
public void someMethod() {
...
sendData(...);
}
then 'mylibrary.dll' contains:
MyDevice device;
JNIEXPORT jint JNICALL Java_com_spongeminded_bluetooth_hci_UsbPort_sendData(JNIEnv *env, jobject obj, jbyteArray packet) {
return device.SendData(...);
}
the exe just calls device.SendData() directly and from above my java program uses the dll to call device.SendData(). i hope i answered your question. thanks. jerry.
> i hope i answered your question.
Yes you did. Thanks.
Hard to say from the information provided yet.
It should work though. The Devil is in the details (as allways :-)
> device's constructor starts some listener events which get queued in the driver to wait for data from the usb device.
Could you post the relevant C++ code that sets the listener events (I'm guessing thread creation, waitforobject, ...).
in the details alright. i never did figure out why that set of code wasn't working but i refined my approach and moved all of the class code into the dll, something i wasn't quite sure how it would turn out. my listeners are completing but i'm running into two problems now that are hopefully minor. i noticed you responded to someone recently about storing a global reference to the JVM and class containing the callback. i inserted the code into my library and the compiler keeps telling me that JNIEnv::'s GetJavaVM and NewGlobalRef don't take 2 arguments, and that JavaVM::AttachCurrentThread doesn't take 3. it looked right to me from jni.h and i removed the overloading syntax but still no go. the second problem is interesting i guess. i've only really tried two cases but in sending one command expecting 7 bytes back from the usb dongle i get 6, none of which appear correct. the other command should return roughly 255 and i get 10- again incorrect. i wouldn't expect any from the device if the data it received was not a recognized command. if i can utilize my java code via the callback it'll make figuring out the latter problem a little easier. thanks again for your help. jerry.
I'm guessing you refer to this thread:
http://forum.java.sun.com/thread.jspa?threadID=763205
You get the errors because what you copied is code made for C, not C++.
You must transform it to C++ for you to have working code: C --> C++
(*env)->GetJavaVM(env, &jvm); --> env->GetJavaVM(&jvm);
obj = (*env)->NewGlobalRef(env, _obj); --> obj = env->NewGlobalRef(_obj);
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL) --> jvm->AttachCurrentThread((void **)&env, NULL)
Regards
note to self- don't rely on watch list notifying me of updates. yes, that's the thread i was referring to. and your fix did work for me. also, upon further inspection of the data received it isn't what i expected but it is correct. just a few changes, adding the call to java and i sholuld be good to go. thank you for your help- it definately expedited the solutions. jerry.