tags:

views:

40

answers:

1

This is my first time using JNI. I need to call a third-party Visual C++ library from a Java program, so I wrote a wrapper in Visual C++. The library loads fine, but when I try to call a function from my wrapper library, I get the dreaded UnsatisfiedLinkError.

My wrapper includes the .h file created by javah, and has the following in the .cpp file:

JNIEXPORT jboolean JNICALL Java_Foo_bar (...)

but the library shows (in PE Explorer) _Java_Foo_bar@32

and my Java code has

public native boolean bar(...) inside class Foo

I suspect the @32 is what's tripping Java up, but I can't figure out how to get rid of it. I don't know much about compiler/linker settings and the like - I've for the most part been able to get away with defaults, or have had someone else handling that portion of a project.

Thanks in advance for any help!

+2  A: 

Try exporting your C++ function as a C function:

extern "C" JNIEXPORT jboolean JNICALL Java_Foo_bar (...)

This turns off name mangling.

Edit: this is indeed not mangling, but "decoration," which apparently is always done for the __stdcall convention that JNI uses. Adding a .def file or a /export linker argument seem to be the solution.

larsmans
There is an extern "C" on the function declaration - do I need it on the definition as well?
eab
I added an extern "C" to the definition and I'm still seeing the same thing in the .dll - is there another switch or something I need to use? I think the @32 is actually called a 'decoration', not mangling.
eab
If I interpret the standard correctly, not if the function is declared before it is defined (e.g., the module defining it includes a header that declares it with "C" linkage).
larsmans
Either way, it's not working. I also tried adding a .def file with an alias. Any other ideas? I'm really stumped. Thanks!
eab
Googled around a bit and devx seems to have the answer. Sun/Oracle's documentation doesn't seem to take this into account.
larsmans
It turned out the @32 wasn't the problem - the problem was packages. I had done javac and javah from the wrong directory. Stupid examples don't explain how to handle packages properly.
eab