DependencyWalker says JNI functions use C, not stdcall (Windows)

  • Thread starter John Perks and Sarah Mount
  • Start date
J

John Perks and Sarah Mount

The header file (with macros replaced) has the declaration:

__declspec(dllimport) jint __stdcall JNI_CreateJavaVM(JavaVM**, void**
void*);

Have just upgraded to Update 5 of Java1.5, and can no longer link
against JVM.DLL. It appears that the program imports the stdcall-mangled
name __imp_JNI_CreateJavaVM@12 but JVM.DLL exports it unmangled. Also,
the Dependency Walker tool says that it is using C linkage, not stdcall.
(If I take off the dllimport, the __imp_ prefix is dropped).

For the VC people: does DependencyWalker examine the actual calling
convention used when listing a function as C or C++ in the export table,
or does it just check if the name is suitably mangled?

For the Java people: is this all as intended? Could it be that
JNI_CreateJavaVM does in fact use stdcall, but has an unmangled name
(presumably for ease or GetProcAddr/dlsym style dynamic loading)?
Shouldn't jni.h (or jni_md.h) have been updated?

For the VC people again: In the above case, how does one link to it with
the unmangled name but using stdcall, and could the function declaration
have been annotated (by some form of #pragma or __declspec) to make it
happen automatically?
And if you could explain what purpose dllimport serves (other than
adding the __imp_ prefix) I'd be grateful.

Thanks

John
 
C

Chris Uppal

John said:
Have just upgraded to Update 5 of Java1.5, and can no longer link
against JVM.DLL. It appears that the program imports the stdcall-mangled
name __imp_JNI_CreateJavaVM@12 but JVM.DLL exports it unmangled. Also,
the Dependency Walker tool says that it is using C linkage, not stdcall.
(If I take off the dllimport, the __imp_ prefix is dropped).

I'm not sure what you're seeing here. The exported functions in JVM.DLL only
changed in one (irrelevant and trivial) way between 1.5.0_0 and 1.5.0_5 (I'm
looking a the 'client' DLLs, but I don't suppose that matters). The
JVM_CreateJavaVM() function is exported undecorated as it has been since at
least 1.2. I don't know whether it has ever been exported decorated /too/, but
it isn't in 1.5, nor in the 1.4.2 DLL I've just checked.

How your program comes to import __imp_JNI_CreateJavaVM@12 puzzles me, but it
puzzles me even more how it could ever have worked.

For the VC people: does DependencyWalker examine the actual calling
convention used when listing a function as C or C++ in the export table,
or does it just check if the name is suitably mangled?

AFAIK, there is no way to tell stdcall from cdecl just by examining a DLL; you
have to rely on guesses based on the name mangling (if any) performed by the
compiler that generated it. Also I don't think that well-written DLLs -- ones
intended to be /dynamically/ linked by programs written in arbitrary languages
(conditions which apply to JVM.DLL) should be exporting "public" functions in
name-mangled form anyway. And indeed that's how (remarkably!) the Sun
engineers have set up their DLL.

For the Java people: is this all as intended? Could it be that
JNI_CreateJavaVM does in fact use stdcall, but has an unmangled name
(presumably for ease or GetProcAddr/dlsym style dynamic loading)?
Shouldn't jni.h (or jni_md.h) have been updated?

JNI_CreateJavaVM() is stdcall and always has been stdcall. It always has been
exported in unmangled form. The header files are correct and always have been.

For the VC people again: In the above case, how does one link to it with
the unmangled name but using stdcall, and could the function declaration
have been annotated (by some form of #pragma or __declspec) to make it
happen automatically?
And if you could explain what purpose dllimport serves (other than
adding the __imp_ prefix) I'd be grateful.

AFAIK, dllimport doesn't have anything to do with name mangling, it's a
directive to the compiler/linker so that they know what you are doing with the
name (and I believe dllimport also causes the compiler to generate a stub
method that will be resolved when the DLL is loaded -- but I'm very, very, hazy
on the details).

I'm speculating that you are using some sort of weird, non-standard,
compiler-specific way of arranging to link (dynamically) with the DLL in your
program. If that's the case then you might be better off trying to find out
what that "magic" is and how it works -- or rather, why it has stopped working.
The Sun-supplied headers do not either provide or make use of any such magic.

Personally, I prefer to be explicit, and load the DLL directly, which has the
very important additional advantage -- for my purposes -- that I can control
/which/ DLL, client or server, 1.4 or 1.5, Sun or IBM, etc) is loaded. Example
code, ripped out of a small test program (and therefore sans error checking),
is:

=======================
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <jni.h>

typedef __declspec(dllimport) jint (__stdcall * CreateJavaVMFunc)(
JavaVM**,
void**,
void*);


// called with the full path to the JVM dll as its only parameter
int
main(int argc, char** argv)
{
// get lib entrypoint
HINSTANCE lib = LoadLibrary(argv[1]);
CreateJavaVMFunc createJavaVM = (CreateJavaVMFunc)GetProcAddress(
lib,
"JNI_CreateJavaVM");

// start JVM
JavaVMInitArgs initArgs;
JavaVMOption options[2] = { { "-verbose:jni" } , { "-Xcheck:jni" } };
initArgs.version = JNI_VERSION_1_2;
initArgs.nOptions = 0;
initArgs.options = options;
initArgs.ignoreUnrecognized = true;
JNIEnv *jniEnv;
JavaVM *javaVM;
createJavaVM(&javaVM, (void**)&jniEnv, &initArgs);

.........
=======================

-- chris
 
J

John Perks and Sarah Mount

Seems to have sorted itself out now. Don't know what I did, though.

Thanks Chris, and sorry to have bothered you.

John
 

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
474,141
Messages
2,570,818
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top