Java JNA updateStructureByReference()故障

Java JNA updateStructureByReference()故障,java,dll,jna,Java,Dll,Jna,这是我第一次使用JNA。我试图做的是在DLL中调用一个函数,该函数采用(C代码)->(无符号长设备类型,NeoDevice*pNeoDevice,int*pNumDevices)…(JNA表单)-> (int,neodedevice.getPointer(),int[]myInt) 作为情妇。函数应该写入结构的字段,我想查看更新的字段 这是我的JNA结构“NeoDevice” import java.util.Arrays; import java.util.List; import com.s

这是我第一次使用JNA。我试图做的是在DLL中调用一个函数,该函数采用(C代码)->(无符号长设备类型,NeoDevice*pNeoDevice,int*pNumDevices)…(JNA表单)-> (int,neodedevice.getPointer(),int[]myInt) 作为情妇。函数应该写入结构的字段,我想查看更新的字段

这是我的JNA结构“NeoDevice”

import java.util.Arrays;
import java.util.List;
import com.sun.jna.*;

public class NeoDevice extends Structure {
    public volatile int DeviceType;
    public volatile int Handle;
    public volatile int NumberOfClients;
    public volatile int SerialNumber;
    public volatile int MaxAllowedClients;
    public NeoDevice() {
       super();
    }
    protected List<? > getFieldOrder() {
         return Arrays.asList("DeviceType", "Handle", "NumberOfClients", "SerialNumber", "MaxAllowedClients");
    }
    public NeoDevice(int DeviceType, int Handle, int NumberOfClients, int SerialNumber, int MaxAllowedClients) {
        super();
        this.DeviceType = DeviceType;
        this.Handle = Handle;
        this.NumberOfClients = NumberOfClients;
        this.SerialNumber = SerialNumber;
        this.MaxAllowedClients = MaxAllowedClients;
    }
    protected ByReference newByReference() { return new ByReference(); }
    protected ByValue newByValue() { return new ByValue(); }
    protected NeoDevice newInstance() { return new NeoDevice(); }

    public static class ByReference extends NeoDevice implements Structure.ByReference {

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

    };
}
事实上,这不是一个公共功能,应该是你做错事的第一个迹象

通过声明您的结构字段
volatile
,您告诉JNA避免将它们的值复制到本机内存中,这通常是在本机函数调用之前自动执行的。这只是一个问题,如果您想要将Java字段中的值传递给本机函数;如果您只对读取结果感兴趣,
volatile
并不重要

如果您的
icsnoFindNeoDevices
声明将
NeoDevice
实例作为其第二个参数(而不是指针),那么JNA将自动正确同步结构字段(它将在函数调用后更新Java字段)。当JNA遇到
结构
参数时,它会在调用之前将所有Java字段写入本机内存,然后根据本机内存进行更新

编辑

根据,
DeviceType
应使用
NativeLong
;您的声明将无法在windows以外的任何64位系统上正常运行

确保您的库正在使用
stdcall
调用约定(名义上这意味着实现
StdCallLibrary
接口)

似乎还为DeviceType提供了一个无效的(“65535”)值;检查
NumDevices[0]
中返回的值是否不为零


您还应该检查返回值;如果为零,则不应期望任何内容写入结构。

感谢您的输入!我只对读回这些值感兴趣。如果没有Structure.updateStructureByReference,在调用函数并尝试查看字段值之后,它们都是零。我目前正在玩弄structure.read()和structure.readField(),以便查看字段,但仍然有问题我也无法访问源代码来更改参数,因此我被迫将NeoDevice作为指针传递,只需删除
volatile
并调用
structure.read()
函数调用后。感谢您的帮助,technomage,但仍然没有取得任何进展。我能看到的唯一错误是我的类定义了我的结构。我将更仔细地研究这个问题。
    NeoDevice.ByReference myDeviceByRef = new NeoDevice.ByReference();
    NeoDevice.ByValue myDeviceByVal = new NeoDevice.ByValue();
    NeoDevice myDevice = new NeoDevice();

    int [] NumDevices;
    NumDevices  = new int [1];
    NumDevices[0] = 1;

    int iResult = n40.icsneoFindNeoDevices(65535, myDeviceByRef.getPointer(), NumDevices);
    int icsneoGetDLLVersion = n40.icsneoGetDLLVersion();

    Object serialN = myDeviceByRef.readField("SerialNumber");
    NeoDevice.ByReference myDeviceBy = Structure.updateStructureByReference(NeoDevice.ByReference, myDeviceByRef, myDeviceByRef.getPointer());