Search code examples
javacheaderjava-native-interfacejavah

How to generate a specific JNI header


I have a .dll library which exports a function in the following format:

_Java_folder1_folder2_folder3_JavaClassName_javamethodname@16

I cannot modify the .dll. It was given to me.

I need to write a java program to call the native javamethodname. However, I have trouble generating the right header file. How can I generate a header file with the signature specified above?

I tried javah -jni JavaClassName, but it does not give me the desired result. When I call javah from inside the directory hierarchy, I get a header like:

Java_JavaClassName_javamethodname

When I try to call javah from outside the directory hierarchy, I get an error.

Also, how do I get the underscore in the header signature in front of Java? That is: _Java not Java.

Thanks!


Solution

  • Writing the java code is easy: you create a Java project with package name folder1.folder2.folder3 and put your class JavaClassName in there with a native javamethodname. You don't need to generate headers or anything, that has been already done by someone who created the DLL and had the same class as you are reconstructing.

    The Java_ prefix is standard and is added by the JVM-JNI linker, you don't need to care about it.

    However, i read between the lines that you have also a problem with the leading underscore. It is a "compiler decoration" and if you got only the DLL (no sources, no recompilation), you might be as well doomed. Various compilers add various "decorations" to ensure that you don't mix up calling convention between the caller (JVM) and callee (DLL). It has some observable default behavior and can be mangled by various compiler options and/or definition files (.def on MSVC). Neither of this is applicable for your case. So you need:

    1. Find out what compiler was used to produce the DLL
    2. Look up the calling convention for which the given compiler produces your observed symbol decoration
    3. Your DLL is runnable only through JVM which has the same calling convention defined as JNICALL macro in $JAVA_HOME/include/your_platform/jni_md.h