JNI与dll文件有关

时间:2013-11-01 14:27:50

标签: java c++ dll java-native-interface

我再次遇到JNI的问题......

这次我的代码工作......但是......在所有PC上都不正确。

我有:

  1. Jar文件 - >我的编程
  2. dll文件 - >使用原生方法
  3. 另一个dll文件 - >与其他功能。
  4. 在我的电脑上,所有这些文件都在一个文件夹中。

    文件代码(.java):

    // loading library
        try {
            Runtime.getRuntime().loadLibrary("E140tests");
            setText("Library E140tests.dll was loaded correctly.");
        } catch (UnsatisfiedLinkError ex) {
            // try load with absolute path
            setText("Error: E140tests.dll wasn't loaded!");
            setErrorFlag(true);
        }
    

    E140tests.dll - >第二个文件(在MSVS中编译)

    #include "jni.h"
    #include "jni_md.h"
    #include "Lusbapi.h"
    #include "LusbapiTypes.h"
    #include "JNITEST2.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /*
     * Class:     JNITEST2
     * Method:    ADCinit
     * Signature: (LJNITEST2;)V
     */
    JNIEXPORT void JNICALL Java_JNITEST2_ADCinit
      (JNIEnv* env, jobject, jobject obj) {
      ...
    

    lusbapi.dll - >第三个文件,带有其他功能。

    #ifndef __LusbapiH__
    #define __LusbapiH__
    
    // --------------------------------------------------------------------------
    // ---------------------------- COMMON PART ---------------------------------
    // --------------------------------------------------------------------------
    #include <windows.h>
    #include "LusbapiTypes.h"
    

    如果我在system32中抛出我的文件,一切都有效。

    但是。在另一台PC(xp,7)中,我的代码不起作用!无所谓:如果文件(+ dll)在一个文件夹中,或者dll文件在system32中 - &gt;代码找不到它们。

    我想,问题出现在运行时库(MSVS)中,但是我安装了它们,没有任何改变......

    (在我的电脑上是IntelijIDEA,MSVS,jdk7.xx - &gt;一切正常。我在另一台PC上安装了测试版(安装了MSVS) - &gt;并且一切正常。但在另一台电脑上 - &gt; dll未找到(以及安装了运行时库)。)。

    我会等待帮助)

3 个答案:

答案 0 :(得分:1)

不幸的是,当你编译.DLL时,它只与匹配架构的系统兼容。

aka:32位.DLL在32位机器上工作,64位同样如此。有一些策略可以解决这个问题(为visual studio购买许可证会为你提供允许这样做的工具,并且会生成特定于平台的.dll),但这意味着你必须将适当的.DLL与你的任何版本的程序捆绑在一起'重新测试。这就是为什么在网站上它会询问你大多数时间都有32位或64位机器。

这也是java很好的主要原因之一,因为它是'平台无关的'(我使用这个术语松散,因为其他东西可以影响它,使其不真实)。

无论哪种方式,只要添加JNI调用,就会添加大量依赖项,这使得分发软件变得更加困难。

答案 1 :(得分:0)

您必须在两种体系结构中编译DLL。对于编译,您可以使用64位系统并使用这些命令进行编译。

对于64位(GCC)

gcc -o E140Tests64.dll -shared -IC:\....\include sourcefile.c

对于32位(GCC)

gcc -o E140Tests.dll -shared -IC:\....\include sourcefile.c

希望这有帮助。

答案 2 :(得分:0)

如果要分发应用程序,则需要构建DLL的32位和64位版本。然后使用以下技术来加载正确的DLL,而不管客户的JVM arch如何。将32或64(MyJniDLL32.dll和MyJniDLL64.dll)附加到生成的输出文件中。

String archDataModel = System.getProperty("sun.arch.data.model");
System.loadLibrary(libraryName+archDataModel);

DLL的arch(32 vs 64)必须与JVM ach(32 vs 64)匹配,而不是OS arch。如果您在64位操作系统上运行32位JVM,则您的Java代码必须能够访问32位DLL。