views:

138

answers:

2

I manage project for JNI for both compilers: MSVC++ 8.0 and 9.0, my cpp file contains following implementation: extern "C" { JNIEXPORT jlong JNICALL Java_context_ServiceProviderContext_StartServiceProvider (JNIEnv * env, jclass, jstring jspath){ ..... }

With help of depends.exe utility I can see that MSVC 8.0 successfully exports function as it is expected: Java_context_ServiceProviderContext_StartServiceProvider But compiling under MSVC 9.0 gets me crazy it exports like ignoring extern "C" at all. depends.exe shows me: _Java_context_ServiceProviderContext_StartServiceProvider@12

Does anybody know what exactly in 9.0 project that causes this behavior?

A: 

That's __stdcall calling convention; you need __cdecl. Maybe try adding __cdecl to your function's definition?

Alternatively, change the default calling convention in the project settings.

user9876
No, thanks - JNI exactly expects __stdcall. And 8.0 has managed it without any problems. And just for your information difference between __cdecl and __stdcall not in decoration, but in order of parameters.
Dewfy
The only difference between __cdecl and __stdcall is who is responsible for popping the parameters off the stack. But yes, calling convention and name decoration are orthogonal to each other.
Aaron Klotz
+1. I vote this up since it solved the problem for me. My dll-export with extern "C" was getting mangled until I removed __stdcall and let the default __cdecl project setting kick in. If the calling convention in itself isn't actually the essense of the solution in this case, maybe one of the other commentators would like to post a new answer shedding light over why this is working.
sharkin
+1  A: 

JNICALL is probably #define JNICALL __stdcall. Changing the calling convention will fix the name decoration, but it will horribly (including silently) break JNI, as it will be calling a function assuming __stdcall and getting something else.

Does it actually not work? From what I can google it seems that the JVM knows how to decorate the function names properly.

MSN
You are right, it is __stdcall, but JVM expects exactly Java_context_ServiceProviderContext_StartServiceProvider. Please note, that all things are correct under MSVC 8.0, I'm pretty sure that problem appears while migration the project.
Dewfy
You can also manually bind the name using the .def file.
MSN