When a function is exported from a DLL the compiler will decorate or mangle the function name. To export the undecorated function name the linker needs an export definition file (.DEF). A while back I was working on a project in Java that calls functions from a DLL using JNI. I had created a DLL that exported some functions to be called from a Java application. Just when I started to test the application I realized that I had forgotten to update the .DEF file. I was expecting the Java application to fail when it would try to call the functions in the DLL. To my surprise, the function calls succeeded. I was curious to find out why these calls succeeded. I wrote a sample Java application that had one class called Hello which would call a native function called sayHello in a DLL called Hello.DLL. Running javah on the Java source generated the header file with a native function named Java_Hello_sayHello. I created the DLL and made sure that the exported function was undecorated. Using the fantastic Dependency Walker’s lightweight profiler I ran the Java application. Looking at the output window in Depends, it was clear why a call to a function in decorated form, would succeed. JNI first tries to call the function using two decorated names before calling it with the undecorated name as illustrated in the image below.
The JNI specification mentions the naming convention for the native function. However, there is no mention of the fact that when calling the functions from a native library the runtime will try to call the functions using both the decorated and undecorated names. Another peculiar behavior that I noticed is that when calling the other JNI related functions that you can export from a native library such as JNI_OnLoad, JNI_OnUnload, the runtime tries only one decorated name before calling the undecorated function as shown above. I find this very strange.