如何使用JNA处理结构内的结构成员?

时间:2013-12-11 11:30:30

标签: java jna

我正在使用JNA在本机函数调用上返回嵌套结构指针。嵌套结构具有unsigned char,struct类型的成员。我能够读取原始类型,但在处理嵌套结构成员时遇到了困难,例如OBISCODE回应。我的嵌套结构如下所示:

typedef struct ObisCode
{
    unsigned char a;
    unsigned char b;
    unsigned char c;
    unsigned char d;
    unsigned char e;
    unsigned char f;
} OBISCODE;

typedef struct Response
{
    unsigned char result;
    OBISCODE obis;
} RESPONSE;

和原生函数:

RESPONSE* getStruct(OBISCODE * obis)

我的Java代码调用此本机函数如下:

package struct;

    import com.sun.jna.Native;
    import com.sun.jna.Pointer;

public class JNATest {

    static {
        Native.register("StructTest"); 
    }


    public static class OBISCODE {
        private Pointer pointer;

        public OBISCODE() {
            long memory = Native.malloc(6);
            pointer = new Pointer(memory);
        }

        public OBISCODE(Pointer pointer) {
            this.pointer = pointer;         
        }

        Pointer getPointer() {
            return pointer;
        }

        int getA() {
            return pointer.getByte(0);
        }

        int getB() {
            return pointer.getByte(1);
        }

        int getC() {
            return pointer.getByte(2);
        }

        int getD() {
            return pointer.getByte(3);
        }

        int getE() {
            return pointer.getByte(4);
        }

        int getF() {
            return pointer.getByte(5);
        }

        void setA(byte a) {
            pointer.setByte(0, a);
        }

        void setB(byte b) {
            pointer.setByte(1, b);
        }

        void setC(byte c) {
            pointer.setByte(2, c);
        }

        void setD(byte d) {
            pointer.setByte(3, d);
        }
        void setE(byte e) {
            pointer.setByte(4, e);
        }
        void setF(byte f) {
            pointer.setByte(5, f);
        }

        void free() {
            Native.free(Pointer.nativeValue(pointer));
        }

    }


    public static native void printStruct(Pointer obis);

    public static native Pointer getStruct(Pointer obis);
    /**
     * @param args
     */
    public static void main(String[] args) {
        try {

            struct.JNATest.OBISCODE obis = new struct.JNATest.OBISCODE();
            obis.setA( (byte) 0);
            obis.setB( (byte)  0);
            obis.setC( (byte)  8);
            obis.setD( (byte)  0);
            obis.setE( (byte)  0);
            obis.setF( (byte)  255);

            Pointer ptr = obis.getPointer();
            System.out.println("ptr = " + ptr.toString());
            printStruct(obis.getPointer());

            Pointer resptr = getStruct(obis.getPointer());
            Response response = new Response(resptr);
            System.out.println("result = " + response.getResult());
            System.out.println("1=" + resptr.getInt(1) + "2=" + resptr.getInt(2)
                    );

            obis.free();

        } catch (UnsatisfiedLinkError e) {
            System.out.println("Exception" + e);
        }
    }
}

我的等效本机结构响应类如下

package struct;

import com.sun.jna.Native;
import com.sun.jna.Pointer;

public class Response {

    private Pointer pointer;

    public Response() {
        long memory = Native.malloc(6);
        pointer = new Pointer(memory);
    }

    public Response(Pointer pointer) {
        this.pointer = pointer;         
    }

    Pointer getPointer() {
        return pointer;
    }

    int getResult() {
        return pointer.getByte(0);
    }

    int getOBIS() {
        return pointer.getByte(1);
    }

    void setResult(byte a) {
        pointer.setByte(0, a);
    }

    void setOBIS(byte b) {
        pointer.setByte(1, b);
    }

    void free() {
        Native.free(Pointer.nativeValue(pointer));
    }

}

我在Redhat Linux中运行此测试,输出如下所示

result = 12
1=5242882=2048

如果我遗漏了Java代码中的某些内容来处理结构,请纠正我。任何帮助是极大的赞赏?提前谢谢。

1 个答案:

答案 0 :(得分:0)

JNA为Structures提供直接支持。

例如:

public class ObisCode extends Structure 
{
    public byte a;
    public byte b;
    public byte c;
    public byte d;
    public byte e;
    public byte f;
    protected List getFieldOrder() { return Arrays.asList(new String[] { "a", "b", "c", "d", "e", "f" }); }
    public OBISCODE() { }
    public OBISCODE(Pointer p) { super(p); read(); }
}

public class Response extends Structure
{
    public byte result;
    public OBISCODE obis;
    protected List getFieldOrder() { return Arrays.asList(new String[] { "result", "obis" }); }
    public Response() { }
    public Response(Pointer p) { super(p); read(); }
}