JNI调用本地库的问题

来源:互联网 发布:淘宝信用卡套现被骗了 编辑:程序博客网 时间:2024/06/09 17:10

这两天和春福在折腾JNI,用Java调用自己开发的C++库,花了两三天时间,最终春福找到了问题所在,搞定了,特此记录一下。

我们先在Windows下用VS2008开发。

需求:有一个C++开发的读取配置文件的component: Conf.dll,Java应用程序也需要读取配置文件,因此需要写一个JNI的wrapper来调用Conf.dll。
写JNI程序总归是那几步:
1.写一个ConfWrapper.java:
public class ConfWrapper {
    
    static{
        if(System.getProperty("os.name").toUpperCase().indexOf("WINDOWS")!=-1){
            System.loadLibrary("ConfWrapper");
        }
        else{
            System.loadLibrary("Conf");    
        }
    }    
    public static native String getParam(String packageName,String moduleName,String paramName);
    
    public static native String getAFCHome();
    
    public static native String getLocalDBConnString();
    
    public static void main(String[] args){
    }
}
getParam getAFCHome getLocalDBConnString分别在Conf中有对应的方法。

2. 调用Javac生成ConfWrapper.class
3. 调用Javah生成JNI头文件,头文件中声明了每个native方法对应的C++方法,根据这个头文件写cpp,在各个方法中先LoadLibrary加载conf.dll,
   然后GetProcAddress获取对应的函数,最后调用获取的函数。把函数调用结果返回。
4. 根据这个头文件和cpp文件,直接调用cl生成ConfWrapper.dll,命令如下:
   cl /D "WIN32"  /I"%JAVA_HOME%/include" /I"%JAVA_HOME%/include/win32" /LD "ConfWrapper.cpp" -FeConfWrapper.dll
   
5. 在ConfWrapper.java的main方法中进行测试,总是失败,Eclipse的报错信息是Access Violation。

这个问题昨天下班的时候还没搞定,春福回到家继续琢磨,找到的问题的过程:
春福不通过Visual studio IDE来生成工程,而是像上面生成ConfWrapper.dll一样,手工写一个头文件和cpp文件,直接用cl编译得到一个dll,他发现这个dll不work,即使在
Visual studio 里面调用这个dll,还是会产生Access violation。但是如果是通过Visual studio IDE来生成一个dll工程,然后把文件加进来,所生成的dll就没有问题。

今天来上班,通过Visual studio IDE来生成一个dll工程,然后把Javah生成的头文件和相应的cpp加到这个工程里面,通过VS2005编译得到ConfWrapper.dll,这个dll果然就成功
了。

根据这个结果,我们比较了步骤4的cl命令行和VS2005生成的命令行,发现少了一些宏定义和其他参数,这应该就是问题所在了。

VS2005生成的命令行(Debug):
/Od /I "C:/Program Files/Java/jdk1.6.0_16/include" /I "C:/Program Files/Java/jdk1.6.0_16/include/win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "undefined_EXPORTS" /D "_WINDLL" /D "_MBCS" /Gm /EHsc /RTC1 /MDd /Fo"Debug//" /Fd"Debug/vc90.pdb" /W3 /nologo /c /Wp64 /ZI /TP /errorReport:prompt
VS2005生成的命令行(Release):
/GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "undefined_EXPORTS" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /FD /EHsc /MD /Fo"Release//" /Fd"Release/vc90.pdb" /W3 /nologo /c /Wp64 /Zi /TP /errorReport:prompt

现在还没时间分析cl的这些参数所带来的库文件的差异,有空来再详细琢磨琢磨。

原创粉丝点击