You are exporting the native routine as a name-mangled C++
function. The reason we can tell this is because the parameters to the function are listed in the export information of the library. Whenever you can tell the types of the parameters that are being passed in the name of a function it implies that the function is being exported as a decorated C++
method. If you looked at the raw export information of the library without demangling, it would look something like:
?Java_Package_ComControl_destroy@@YGXPAUJNIEnv_@@PAV_jobject@@@Z
When it looks like this, the java run-time cannot find it, it is supposed to look more like:
_Java_Package_ComControl_destroy@8
which is an undecorated C
routine. The @8
is stdcall shorthand for 8 bytes are passed in the stack to the routine
The most common reason for this happening is that the .h
file which declares the function and was generated by javah does not match the .cpp
file that defines the content of the function - i.e. there is some subtle difference between the .h
file and the .cpp
file. You should copy-paste the declaration of the function in the .h
file into the .cpp
file, making sure that all the parameters line up and that all the types line up.
Additionally, for the .cpp
file, you have to make sure that it #include
s the .h
file that was generated by javah, and doesn't just does #include <jni.h>
. If you don't do this then the compiler will not know that the routine is to be exported as a C
style routine. This is a common reason why the resulting compiled dll does not contain the unmangled version of the method.
If you want to manually enforce the routines being exported using the undecorated C
calling convention, in the .cpp
file, at the function definition, you can put in:
extern "C"
JNIEXPORT void JNICALL
Java_com_optin_executableContainer_client_COMControl_setControlBackColor
(JNIEnv *env, jobject obj, jlong color)
{
printf("\nHello World\n");
}
By using the extern "C"
in that manner, the function will be defined for export as a C
routine rather than a C++
routine; but this is undesirable as you should really be including the .h
that came from javah
.
I don't know if visual studio has an equivalent to the -Wmissing-declarations
of gcc
which notices inconsistencies like this, which are kind of important for .dll
s.