JNA复杂的联合结构映射

时间:2015-01-08 07:38:59

标签: structure union jna

在JNA中,如何从以下c代码映射复杂的联合结构:

typedef struct {
   char *vmxSpec;     
   char *serverName; 
   char *thumbPrint;  
   long privateUse;   
   VixDiskLibCredType credType;//enum type

   union VixDiskLibCreds {
      struct VixDiskLibUidPasswdCreds {
         char *userName; 
         char *password; 
      } uid;
      struct VixDiskLibSessionIdCreds {
         char *cookie;
         char *userName;
         char *key;
      } sessionId;
      struct VixDiskLibTicketIdCreds *ticketId; 
   } creds;

   uint32 port;
} VixDiskLibConnectParams;

当我映射结构时,它会抛出NullPointerException:

Exception in thread "Thread-56" java.lang.NullPointerException
    at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
    at java.util.Arrays.sort(Arrays.java:472)
    at java.util.Collections.sort(Collections.java:155)
    at com.sun.jna.Structure.sort(Structure.java:889)
    at com.sun.jna.Structure.getFields(Structure.java:921)
    at com.sun.jna.Structure.deriveLayout(Structure.java:1054)
    at com.sun.jna.Structure.calculateSize(Structure.java:978)
    at com.sun.jna.Structure.calculateSize(Structure.java:945)
    at com.sun.jna.Structure.allocateMemory(Structure.java:375)
    at com.sun.jna.Structure.<init>(Structure.java:184)
    at com.sun.jna.Structure.<init>(Structure.java:172)
    at com.sun.jna.Structure.<init>(Structure.java:159)
    at com.sun.jna.Structure.<init>(Structure.java:151)
    at com.test.vmm.vdp.VixDiskLibrary$VixDiskLibConnectParams.<init>(VixDiskLibrary.java:71)
    at com.test.vmm.vdp.VixDiskLibrary$VixDiskLibConnectParams$ByReference.<init>(VixDiskLibrary.java:72)
    at com.test.vmm.vdp.VixDiskLib.run(VixDiskLib.java:47)
    at java.lang.Thread.run(Thread.java:744)

我的代码如下:

public static class VixDiskLibConnectParams extends Structure {
        public static class ByReference extends VixDiskLibConnectParams implements Structure.ByReference {}
        public static class ByValue extends VixDiskLibConnectParams implements Structure.ByValue {}

        public static class VixDiskLibCreds extends Union {
            public static class ByReference extends VixDiskLibCreds implements Structure.ByReference {}
            public static class ByValue extends VixDiskLibCreds implements Structure.ByValue {}

            public VixDiskLibUidPasswdCreds uid;
            public VixDiskLibSessionIdCreds sessionId;
            public VixDiskLibTicketIdCreds.ByReference ticketId;

            public static class VixDiskLibUidPasswdCreds extends Structure {
                public static class ByReference extends  VixDiskLibUidPasswdCreds implements Structure.ByReference {}
                public String userName;
                public String password; 

                protected List getFieldOrder() {
                    List list = new ArrayList();
                    list.add(userName);
                    list.add(password);
                    return list;
                }
            }

            public static class VixDiskLibSessionIdCreds extends Structure { 
                public static class ByReference extends VixDiskLibSessionIdCreds implements Structure.ByReference {}
                public String cookie;
                public String userName;
                public String key;

                protected List getFieldOrder() {
                    List list = new ArrayList();
                    list.add(cookie);
                    list.add(userName);
                    list.add(key);
                    return list;
                }
            }

            public static class VixDiskLibTicketIdCreds extends Structure {
                public static class ByReference extends  VixDiskLibUidPasswdCreds implements Structure.ByReference {}
                protected List getFieldOrder() {
                    List list = new ArrayList();
                    return list;
                }
            }

            protected List getFieldOrder() {
                List list = new ArrayList();
                list.add(uid);
                list.add(sessionId);
                list.add(ticketId);
                return list;
            }
        }

        public String vmxSpec;   
        public String serverName;  
        public String thumbPrint; 
        public NativeLong privateUse;  
        public int credType;
        public VixDiskLibCreds.ByValue creds;
        public int port;

        public void read() {
            super.read();
            switch (credType) {
            case VixDiskLibCredType.VIXDISKLIB_CRED_UID:
                creds.setType(VixDiskLibCreds.VixDiskLibUidPasswdCreds.class);
                creds.read();
                break;
            case VixDiskLibCredType.VIXDISKLIB_CRED_SESSIONID:
                creds.setType(VixDiskLibCreds.VixDiskLibSessionIdCreds.class);
                creds.read();
                break;
            case VixDiskLibCredType.VIXDISKLIB_CRED_TICKETID:
                creds.setType(VixDiskLibCreds.VixDiskLibTicketIdCreds.class);
                creds.read();
                break;
            case VixDiskLibCredType.VIXDISKLIB_CRED_SSPI:
                System.out.println("VixDiskLibCredType : VIXDISKLIB_CRED_SSPI");
                break;
            default:
                System.out.println("VixDiskLibCredType : unknow");
                break;
            }
        }

        protected List getFieldOrder() {
            List list = new ArrayList();
            list.add(vmxSpec);
            list.add(serverName);
            list.add(thumbPrint);
            list.add(privateUse);
            list.add(credType);
            list.add(creds);
            list.add(port);
            return list;
        }
    }

出了什么问题?明确解释如何做到这一点会更好。 感谢

1 个答案:

答案 0 :(得分:0)

我发现了问题,在调用按List添加元素时,方法add()中的引号被遗忘了 正确的代码是:

protected List getFieldOrder() {
     List list = new ArrayList();
     list.add("userName");
     list.add("password");
     return list;
}