0

我对 JNA 很陌生。我有一个问题,我将结构传递给更新一些变量的库调用。当我从 main 方法直接在 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 的对象中获得这些值。

任何帮助,将不胜感激!

4

1 回答 1

1

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

Union.setType(Class)如果您知道,请在通话前致电;否则在本机调用之后调用它,然后是Structure.read().

于 2013-05-03T01:29:35.733 回答