JNA传递的值不是更新

时间:2013-05-02 20:12:31

标签: java c dll jna

我对JNA很新。我有一个问题,即我将一个Structure传递给一个更新一些变量的库调用。当我从主方法直接在C代码中执行它时,它可以工作,但是当我尝试使用JNA访问它时,值不会更新。

我想要获取的值是:ser,serName,hw,hwName,oem,oemName

我试图在JNA中访问的方法:

__declspec(dllexport) Bool _cdecl
GetSN(
        DevProgramInfo           * pDevProgInfo,
        unsigned char              sessionID) {


    unsigned char                   * pCmd;
    unsigned short                    cmdLen = 0;
    Platform_Access_Get_SN_Payload     * pBufGetSN;

    pCmd = (unsigned char *)&Cmd;
    pBufGetSN = (Platform_Access_Get_SN_Payload *)&Payload;

    ClearMsgHeader((Message *)pCmd);

    Platform_Get_SN(pCmd, sessionID, &cmdLen, (unsigned char *)pBufGetSN);
    USBWriteToDevice(&pDevProgInfo->deviceInfo, pCmd, &cmdLen);
    USBReadFromDevice(&pDevProgInfo->deviceInfo, pCmd);
    Platform_Get_SN(pCmd, sessionID, &cmdLen, (unsigned char *)pBufGetSN);

    pDevProgInfo->sn.sn.ser = pBufGetSN->resp.ser;
    strcpy((char *)pDevProgInfo->sn.sn.serName, (char *)pBufGetSN->resp.serName);
    pDevProgInfo->sn.sn.hw = pBufGetSN->resp.hw;
    strcpy((char *)pDevProgInfo->sn.sn.hwName, (char *)pBufGetSN->resp.hwName);
    pDevProgInfo->sn.sn.oem = pBufGetSN->resp.oem;
    strcpy((char *)pDevProgInfo->sn.sn.oemName, (char *)pBufGetSN->resp.oemName);

    return TRUE;
}

这个方法的JNA声明是

public boolean GetSN(DevProgramInfo devInfo, byte sessionID);

我在Java中构建了结构,这里是在java中创建的“sn.sn”

public class mySN extends Union {
    /// C type : field_struct

    public field_struct field;
    /// C type : sn_struct
    public sn_struct sn;
    /// <i>native declaration : line 3</i>
    /// <i>native declaration : line 3</i>

    public static class field_struct extends Structure {
        /// unique to each pid+version+variant

        public NativeLong sequence;
        public byte variant;
        public byte version;
        public short pid;

        public field_struct() {
            super();
        }

        protected List getFieldOrder() {
            return Arrays.asList("sequence", "variant", "version", "pid");
        }

        public field_struct(NativeLong sequence, byte variant, byte version, short pid) {
            super();
            this.sequence = sequence;
            this.variant = variant;
            this.version = version;
            this.pid = pid;
        }

        public static class ByReference extends field_struct implements Structure.ByReference {
        };

        public static class ByValue extends field_struct implements Structure.ByValue {
        };

        public boolean copy(field_struct fieldInfo) {
            this.sequence = fieldInfo.sequence;
            this.variant = fieldInfo.variant;
            this.version = fieldInfo.version;
            this.pid = fieldInfo.pid;
            return true;
        }
    };
    /// <i>native declaration : line 9</i>
    /// <i>native declaration : line 9</i>

    public static class sn_struct extends Structure {

        public NativeLong ser;
        public byte[] serName = new byte[20];
        public NativeLong hw;
        public byte[] hwName = new byte[20];
        public NativeLong oem;
        public byte[] oemName = new byte[20];

        public sn_struct() {
            super();
        }

        protected List getFieldOrder() {
            return Arrays.asList("ser", "serName", "hw", "hwName", "oem", "oemName");
        }
        public sn_struct(NativeLong ser, byte serName[], NativeLong hw, byte hwName[], NativeLong oem, byte oemName[]) {
            super();
            this.ser = ser;
            if (serName.length != this.serName.length) {
                throw new IllegalArgumentException("Wrong array size !");
            }
            this.serName = serName;
            this.hw = hw;
            if (hwName.length != this.hwName.length) {
                throw new IllegalArgumentException("Wrong array size !");
            }
            this.hwName = hwName;
            this.oem = oem;
            if (oemName.length != this.oemName.length) {
                throw new IllegalArgumentException("Wrong array size !");
            }
            this.oemName = oemName;
        }

        public static class ByReference extends sn_struct implements Structure.ByReference {
        };

        public static class ByValue extends sn_struct implements Structure.ByValue {
        };
    };

    public mySN() {
        super();
    }
    /// @param sn C type : sn_struct

    public mySN(sn_struct sn) {
        super();
        this.sn = sn;
        setType(sn_struct.class);
    }
    /// @param field C type : field_struct

    public mySN(field_struct field) {
        super();
        this.field = field;
        setType(field_struct.class);
    }

    public static class ByReference extends mySN implements Structure.ByReference {
    };

    public static class ByValue extends mySN implements Structure.ByValue {
    };
}

当我使用代码时

myJNA.getSN(devInfo, (byte) 0);

所有变量(ser,serName,hw,hwName,oem,oemName)都是0。我已经被困在这个问题上大约一个星期了,我似乎无法弄清楚这个问题。

当我将printf添加到DLL时,会在那里的结构中生成正确的值,但是我没有在Java中的对象中获取这些值。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

您正在使用Union。除非你设置“active”类型,否则JNA只能自动读回原始字段(你不希望它回读一个union的'const char *`字段,如果它实际上只是一个值为零的整数)。 / p>

如果您知道,请在通话前拨打Union.setType(Class);否则在本地呼叫之后调用它,然后Structure.read()