小沃最近在开发jni代码,无意间发现了一点很神奇的现象。由于小沃自己的OA是64位的windows7系统,因此小沃一开始使用的是64位的jdk配上64位的mingw。
开发过程还算顺利,64位的mingw生成的dll很快就编译通过,并且成功通过java导入成功了。然后小沃立刻将代码移植到32位的生产环境中去。问题出现了。
在小沃苦逼的程序员的一生中从未遇到过类似这样的,完全一样的代码,64位的编译后可以跑,32位的编译后不可以跑的情况。
小沃曾今一度绝望,在极度绝望以及不甘心的情况下。考虑到大多数windows程序员的习惯,确定尝试一下一个在windows下比较主流的c开发工具---VC++6.0,是的,就是那个传说中20年前的开发工具。使用完全相同的代码,用VC++6.0编译了一个dll,然后尝试使用jni加载到Java中。最后,居然,居然成功了。。。
不甘心的小沃决定调查出事情的真相,小沃写了一个很简单的C语言代码。
#include "jni.h" JNIEXPORT jint JNICALL Java_cn_worldflyng_jni_NativeFunc_CheckDll(JNIEnv *je, jclass jc) { return 0; }
然后分别通过gcc生成一个dll,再通过VC++6.0 生成一个dll,最后通过dll函数查看器,打开这两个dll,并且对比两个函数。
真相大白:
这是通过gcc编译的dll
这是通过VC++6.0生成的dll
看到了吧,VC++6.0生成的dll在函数前添加了一个_,但是gcc生成的dll并没有在函数前添加一个_。
因此,小沃大胆的设想,如果在源代码的函数名前添加一个_,那是不是就说明我们可以直接使用gcc编译出dll,而且可以正常的被java挂在呢。。。
实验证明,小沃的设想是正确的,至于为什么32位系统的dll会在函数名前添加一个_,这一点小沃就不清楚了。可能是历史原因导致的吧。