1

I'm trying to write a set of JNI calls to use some C++ code in my java project. When I write it as C code and compile with GCC, it seems to be fine and the function names are correct (Java_myPackage_MyClass_myFunction).

But I'm finding it easier to do what I want in C++ instead of C. When I try to compile the code I have with C++, the header files for all I can see are correct, everything looks fine, but when I compile it, the dll generated by g++ causes this error in my java code:

Exception in thread "main" java.lang.UnsatisfiedLinkError: package.class.function(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
at package.class.function(Native Method)

When I check the dll in dependency walker, the function has the wrong name to it, it's been changed to _Z52Java_package_class_functionP7JNIENV_P8_jobjectP8_jstringS4_

when I think it should just be showing up in dependency walker as Java_package_class_function

This is the command I'm using to compile the dll with g++

g++.exe -Wl,--add-stdcall-alias -I "C:\Program Files\Java\jdk1.8.0_73\include" -I "C:\Program Files\Java\jdk1.8.0_73\include\win32" -shared -o C:/repos/myproject.dll myproject.cpp -lssl -lcrypto

Is there something I'm missing in compilation? I do have the functions in my .h file listed as JNExport and wrapped in extern "C" {}. I'm just not entirely clear why the function naming/calls get changed when it compiles.

Environment is G++ compiling in Cygwin on Win7 with JDK 1.8 for Java.

function declarations in my .h file:

extern "C" {
JNIEXPORT jstring JNICALL Java_package_class_function(JNIEnv *, jclass, jstring, jstring);

JNIEXPORT jstring JNICALL Java_package_class_function(JNIEnv *, jclass, jstring, jstring);


char * aes_encrypt_string(char *, char *, char *);
char * aes_decrypt_string(char *, char *, char *);

}

I have the externc on there, and the aes functions are being exported correctly in the .dll file, but the other 2 functions are getting the extra decoration.

jspriggs
  • 403
  • 1
  • 5
  • 15

1 Answers1

0

C++ compilers uses name mangling to create unique entries in the symbol table. This isn't needed in C code since each function must already be unique. To prevent name mangling wrap your function definitions in extern "C" { }

For more information see in-c-source-what-is-the-effect-of-extern-c and a duplicate of your question.

Community
  • 1
  • 1
walsht
  • 196
  • 1
  • 10
  • I do have the declarations in the .h file wrapped in extern c. I'll add the gist of my .h file to the question above – jspriggs Apr 25 '16 at 18:35
  • Using extern "C" will also mean that the code must be C, not C++. So this is not the full answer. What the OP might also investigate is the --add-stdcall-alias compiler flag. – mavavilj Dec 24 '22 at 11:31