load native lib (SWT) with JNI on windows

Tom Tromey tromey@redhat.com
Thu Nov 21 07:12:00 GMT 2002

>>>>> "Ranjit" == Ranjit Mathew <rmathew@hotmail.com> writes:

Ranjit> the "org.eclipse.swt.internal.win32.OS" class declares (and
Ranjit> swt-win32-2049.dll defines) JNI methods that have the *same
Ranjit> name as Win32 API functions*! Ugh!

Yes, that's part of the SWT philosophy.  This is actually not the
grossest part of SWT -- look in the *java* code for the pointer
arithmetic.  And the hard-coded `4' meaning `sizeof (void*)'!

Ranjit> In any case, it turned out that the SWT DLL exports
Ranjit> JNI native methods as "_Java_foo_Bar" as opposed to
Ranjit> all the GCC created DLLs that I'd been working with all
Ranjit> the while that export JNI native methods as "Java_foo_Bar".
Ranjit> So I had to modify LookupJNIMethod (jni.cc) with a kludge
Ranjit> where it first looks for "Java_foo_Bar" and then (only
Ranjit> for Windows) looks for "_Java_foo_Bar".

This is interesting.  Is adding a `_' part of the Windows ABI?  If so,
does gcc not follow it on purpose?  It seems to me that perhaps
libltdl ought to take care of this detail for libgcj.  If not (there's
good arguments on either side, I guess), we can add a platform-neutral
"need to add _" #define to libgcj.

Ranjit> The SWT JNI IsDBCSLeadByte method takes a single "byte"
Ranjit> parameter - together with the implicit "JNIEnv *" and
Ranjit> "jclass *", GCJ calculates the parameters to take up
Ranjit> 9 bytes and not 12 bytes as the function expects.

Ranjit> Apparently the stdcall convention uses an "@nn" suffix
Ranjit> for function names where "nn" is the *number of bytes
Ranjit> popped off the stack by the function* and not just "number
Ranjit> of bytes in the argument list" as the MSDN documentation
Ranjit> would have us believe:

Actually, the two aren't in conflict.  I bet what's going on is that
we need to compute the size of the *promoted* arguments, not the size
of the declared arguments.

So all integral types whose size is < sizeof(int) will be promoted to
int, and float will be promoted to double.

Applying this rule gets us `12' in the example you cite.

Ranjit> To paraphrase Alice (to reflect Anthony's sentiments):
Ranjit> "It is getting grosser and grosser!" ;-)

Yes.  Good work tracking all this stuff down though.
You're on the list in case I ever get around to calling the t-shirt
company again :-)

Ranjit> 1. GCJ searches for "JNI_OnLoad" in a loaded DLL - this
Ranjit>     symbol has to change on Windows to use the suffix
Ranjit>     implied by stdcall.

Good catch.  Anywhere we call lt_dlsym or _Jv_FindSymbolInExecutable
is a place to look for this sort of thing.  Seems to me that here we
could have a per-platform #define (with the default being what is
there now).

Does it need to search for _JNI_OnLoad?  If not, why does this differ
from the other native functions in the user's DLL?

Ranjit> 2. It never searches for, nor invokes, "JNI_OnUnload".
Ranjit>     Is that because DLLs are never explicitly unloaded?

Yes.  They are never unloaded at all.


More information about the Java mailing list