Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DLL interoperability issues

48 views
Skip to first unread message

tech...@yahoo.com

unread,
May 11, 2013, 9:16:41 PM5/11/13
to
Hi. I have used lcc-win32 for quite a while to write native interfaces for my Java applications. At present I am implementing an interface to libusb-win32 (USB driver) that should work on both 32 bit and 64 bit systems. Despite it's name this project provides both 32 bit and 64 bit DLLs. Unfortunately the 64 bit version gives me some trouble. It appears that char arrays are packed differently in memory in the lcc generated DLL vs. the DLL from libusb-win32.

I am guessing on a packing issue, because data tends to get corrupted in the handover between the DLLs. In those cases I tend to see most of the data I am handing over, but the 'correct' values show up in unexpected places at the other end. But when thinking about different ways the bytes might be stored in RAM it seems to make sense. Also, I have found a 'magic fix' that seems to make it all work. It involves declaring a char array in the code just before the critical section (where the data gets corrupted). Even though I am not making any use of that array it seems to have impact on the generated code.

Am I missing something, like using a particular compiler switch or could that be a bug in the compiler?

Thanks for any help anyone can give.

jacob navia

unread,
May 12, 2013, 5:40:14 AM5/12/13
to
Le 12/05/13 03:16, tech...@yahoo.com a �crit :

Hi

Have you the dll that is failing?

How does it fail?


I would need a test case where I can see if the compiler has generated
wrong code.

Try to isolate WHEN the data is getting corrupted. Accessing some of
your variables?

You say if you put some data before, the crash doesn't happen. This
points to a buffer overrun. Look at the code that accesses that
data area. Do you respect the bounds?

Look at the data layout. What variable is stored BEFORE the critical
part? It is that one (probably) that is making problems.

jacob

tech...@yahoo.com

unread,
May 12, 2013, 1:54:13 PM5/12/13
to
Jacob,

thanks for your quick reply. Yes, I think I am honoring the array bounds. I am using the same variable to define the array size that I then use to control the loop for copying data into the buffer. Also, the 32 bit version is running fine with or without the 'magic variable'. I added code to dump the data to stdout after copying and that looks good. Then, when I look at the USB bus analyzer to see the data that is actually transmitted to the device I see that it's not the same. The same type of problem also occurs in the reverse direction.

I could get you the code if there is a way to do this without making it public. Debugging it on your end will be more tricky, because you need the USB device to talk to and the Java application to drive it. I'll think about what I could do to construct a test case that makes sense. For the time being here is one of the functions that make trouble. Maybe that gives you something to work with.

<pre>
/*----------------------------------------------------------------------------*/
/**
* Performs a control request to the default control pipe on a device.
*
* @param env the Java environment
* @param obj our Java counterpart object
* @param handle the device handle
* @param requestType USB specification Table 9-2: <code>bmRequestType</code>
* @param request USB specification Table 9-2: <code>bRequest</code>
* @param value USB specification Table 9-2: <code>wValue</code>
* @param index USB specification Table 9-2: <code>wIndex</code>
* @param bytes the data to transfer
* @param timeout the communication timeout in ms to use for the operation
*
* @return The data received from the device. In case of an OUT message
* this will be an empty array. If <code>null</code> is returend
* the call was not successful.
*/
/*----------------------------------------------------------------------------*/
JNIEXPORT jboolean JNICALL Java_com_yxis_lib_usb_LibUSB_usbControlMessage (JNIEnv *env,
jobject obj,
jint handle,
jint requestType,
jint request,
jint value,
jint index,
jintArray bytes,
jint timeout)
{
jboolean result = FALSE;
jboolean isCopy = FALSE;

// ----------------------------------------------------
// re-package the data array
// ----------------------------------------------------
int *source;
jsize size = (*env)->GetArrayLength (env, bytes);
char buffer [size];

source = (*env)->GetIntArrayElements (env, bytes, &isCopy);

// ----------------------------------------------------
// I don't know what is going on, but this line of code
// makes it work for the 64 bit compiler, even though
// it isn't actually doing anything that has impact...
// ----------------------------------------------------
unsigned int magicBuffer [size];

for (int i = 0; i < size; i++)
{
buffer [i] = (char)source [i];
}

(*env)->ReleaseIntArrayElements (env, bytes, source, JNI_ABORT);

// ----------------------------------------------------
// make the call
// ----------------------------------------------------
int callResult = usb_control_msg (handleMap [handle].deviceHandle,
CONTROL_OUT (requestType),
request,
value,
index,
buffer,
(int)size,
timeout);

// ----------------------------------------------------
// check for success. We should have exactly as many bytes
// transfered as asked for by the caller.
// ----------------------------------------------------
if (callResult == size)
{
result = TRUE;
}

return (result);
}
</pre>

tech...@yahoo.com

unread,
May 12, 2013, 2:13:40 PM5/12/13
to
One more thing: I am compiling with lcc64 version 4.1 dated April 1. and I am testing on Windows 7 both on a 32 bit and two 64 bit systems.

tech...@yahoo.com

unread,
May 24, 2013, 1:03:33 PM5/24/13
to
Jacob, I was wondering if you were able to to find anything out about this issue. If not, I might try to construct a test case for the problem. I know the orginal case is not an option because hardware is involved, but perhaps I can come up with something else.

jacob navia

unread,
May 24, 2013, 5:59:10 PM5/24/13
to
Le 24/05/13 19:03, tech...@yahoo.com a �crit :
Sorry but I can't help you if I have no test case...

How could I do that?

Try to isolate the bug. I pointed out several possibilities in my answer
earlier.


Just try to see what address is getting corrupted. That isvery easy.

Put the buffer before the variable that hides the bug.

Put known values in that buffer.

In special places in your program test if the buffer still holds all the
values correctly.

In this way you will find when the buffer gets corrupted.

jacob
0 new messages