Java : switching between dll depends on system arc

2019-02-20 13:10发布

问题:

I have a Java program uses some dlls. As these embeded dlls have to be built for a specific system architecture (32 or 64bits) I want to make a method/something that allow my program to switch between 32/64 bits version of dlls (or disable the library load if the program run on a 64 bits system)

I hope there is a solution different from making two versions of the program

Thanks in advance, Damien

回答1:

Use system properties:

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


回答2:

You can use the System Property 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
}

Careful: this property is defined on Sun VMs only!

Reference:

  • Java HotSpot FAQ > When writing Java code, how do I distinguish between 32 and 64-bit operation?


回答3:

A brute force way is to run

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:

If you're using OSGi and JNI, you can specify the DLLs appropriate for different platforms and architectures in the manifest via Bundle-NativeCode.

For example:

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


回答5:

Define a java interface that represents your DLL API and provide two implementations, one that calls the 32 bit DLL and another one that calls the 64 bit version:

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();
    }
}