How to set global memory byte alignment for all st

2019-07-13 06:20发布

问题:

Is there any way to set global memory byte alignment for all data structures in JNA library (*.dll Java wrapper)?

Sometimes I have to determine correct alignment by trial and error during implementation and currently I'm doing this in very clumsy way - I'm setting data alignment (super(ALIGN_NONE)) in each and every structure (a lot of structures in separate files).

edit: The best way to solve my problem was to extend Structure:

public abstract class StructureAligned extends Structure {
    public static final int STRUCTURE_ALIGNMENT = ALIGN_NONE;

    protected StructureAligned() {
        super(STRUCTURE_ALIGNMENT);
    }

    protected StructureAligned(Pointer p) {
        super(p, STRUCTURE_ALIGNMENT);
    }
}

..but this led to next question: Which (Pointer) constructor is better and why:

super(p, STRUCTURE_ALIGNMENT);

or

super(STRUCTURE_ALIGNMENT);
read();

or

super(STRUCTURE_ALIGNMENT);
useMemory(p);
read();

?

回答1:

Make your own Structure subclass and call the appropriate constructor with the desired alignment type, or call setAlignType() in the constructor.

If JNA is not correctly calculating the appropriate default alignment for the most commonly used compiler on the platform, then you should file a bug against JNA.

If, however, you have a library that simply uses a bunch of arbitrary alignments for its own internal reasons, then turning off alignment for all your Structure classes via a common base class is more appropriate.



回答2:

To make this apply globally, update the default value in the Native library options map when your library is instantiated

public class MyLibrary implements Library {
    static {
        Native.register(MyLibrary.class, NativeLibrary.getInstance("somenativelib"));
        Native.getLibraryOptions(MyLibrary.class).put(Library.OPTION_STRUCTURE_ALIGNMENT, Structure.ALIGN_NONE);
    }
}