【问题标题】:Java : switching between dll depends on system architecture (32/64)Java:d​​ll之间的切换取决于系统架构(32/64)
【发布时间】:2011-07-19 18:31:52
【问题描述】:

我有一个 Java 程序使用一些 dll。由于必须为特定的系统架构(32 位或 64 位)构建这些嵌入的 dll,我想创建一个方法/东西,允许我的程序在 32/64 位版本的 dll 之间切换(或者如果程序运行则禁用库加载在 64 位系统上)

我希望有一个不同于制作两个版本的程序的解决方案

提前致谢, 达米安

【问题讨论】:

    标签: java dll 32bit-64bit switch-statement


    【解决方案1】:

    使用系统属性:

    if ("x86".equals(System.getProperty("os.arch"))) {
       // 32 bit
    } else if ("x64".equals(System.getProperty("os.arch"))) {
       // 64 bit
    }
    

    【讨论】:

    • 好的,在我的旧 PPC Mac 上会发生什么?
    • 如果再做一个?我认为这个想法很清楚,这只是一个代码示例。
    • os.arch 在我的机器上是 amd64
    【解决方案2】:

    您可以使用系统属性sun.arch.data.model

    String dataModel = System.getProperty("sun.arch.data.model");
    if("32").equals(dataModel){
        // load 32-bit DLL
    }else if("64").equals(dataModel){
        // load 64-bit DLL
    }else{
        // error handling
    }
    

    小心:此属性仅在 Sun VM 上定义!

    参考:

    【讨论】:

      【解决方案3】:

      蛮力的方法是跑

      boolean found = false;
      for(String library: libraries)
          try {
              System.loadLibrary(library);
              found = true;
              break;
          } catch(UnsatisfiedLinkError ignored) {
          }
      if(!found) throw new UnsatifiedLinkError("Could not load any of " + libraries);
      

      【讨论】:

        【解决方案4】:

        如果您使用 OSGi 和 JNI,您可以通过 Bundle-NativeCode 在清单中指定适用于不同平台和架构的 DLL。

        例如:

            Bundle-NativeCode: libX.jnilib; osname=macOSX, X.dll;osname=win32;processor=x86
        

        【讨论】:

        • 同名的库呢?我必须为 ARM 和 x86 架构导入 rxtx 库,并且在这两种情况下,该库都称为 librxtxSerial.so。我如何使用此标头区分它们??
        • @marbal - 我想你会列出库两次,一次用于processor=86,一次用于processor=ARM_le(用于小端)或processor=ARM_be(用于大端)。这些值和其他值可以在osgi.org/Specifications/Reference#processor 的表中找到。
        • 我创建了一个名为“lib”的文件夹和 2 个名为“x86”和“arm”的子文件夹,我在每个文件夹中都放入了分别为处理器 x86 和 arm 构建的库。然后,在标题中,我写了这个:lib/x86/librxtxSerial.so; processor=x86, lib/arm/librxtxSerial.so; processor=ARM_le,但每次我得到同样的错误:No match found for native code: 。我做错了什么?
        • 我在这里描述了这个问题:stackoverflow.com/questions/32625924/…
        【解决方案5】:

        定义一个代表您的 DLL API 的 java 接口并提供两种实现,一种调用 32 位 DLL,另一种调用 64 位版本:

        public interface MyDll {
            public void myOperation();
        }
        
        public class My32BitDll implements MyDll {
            public void myOperation() {            
                // calls 32 bit DLL
            }
        }
        
        public class My64BitDll implements MyDll {
            public void myOperation() {            
                // calls 64 bit DLL
            }
        }
        
        public class Main {
            public static void main(String[] args) {
                MyDll myDll = null;
        
                if ("32".equals(args[0])) {
                    myDll = new My32BitDll();
                } else if ("64".equals(args[0])) {
                    myDll = new My64BitDll();
                } else {
                    throw new IllegalArgumentException("Bad DLL version");
                }
        
                myDll.myOperation();
            }
        }
        

        【讨论】:

        • 我怀疑这是 OP 想要的。它迫使用户告诉程序它是在 32 位还是 64 位环境中运行。程序应该自己发现。
        猜你喜欢
        • 2011-12-18
        • 2019-01-03
        • 1970-01-01
        • 2015-07-18
        • 1970-01-01
        • 2012-05-18
        • 1970-01-01
        • 2015-02-11
        • 1970-01-01
        相关资源
        最近更新 更多