JNA updateStructureByReference() trouble

2019-09-06 02:04发布

问题:

this is the first time I am using JNA. What I am trying to do is call a function in a DLL that takes (C code)->(unsigned long DeviceTypes, NeoDevice *pNeoDevice, int *pNumDevices)...(JNA form)-> (int, NeoDevice.getPointer(), int[] myInt) as params. The function should write to the fields of the struct and I want to view the updated fields.

here is my JNA struct '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 {

    };
}

I am attempting to use 'updateStrucureByReference(class type, object, pointer to object)' to update the fields. I dont believe my 'class type' param is correct or is it? am i doing something else wronge? any input would be greatly appreciated.

when i try to println the fields they appear to all be zero still.

In my main class i have

    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());

回答1:

The fact that Structure.updateStructureByReference is not a public function should be your first indication that you're doing something wrong.

By declaring your structure fields volatile, you are telling JNA to avoid copying their values to native memory, which it ordinarily does automatically prior to a native function call. This is only a problem if you intend for values in the Java fields to be passed to the native function; if you're only interested in reading back the results, volatile doesn't matter.

If your icsneoFindNeoDevices were declared to take a NeoDevice instance as its second argument (rather than a pointer), then JNA would automatically synch the structure fields properly (it will update the Java fields after the function call). When JNA encounters a Structure argument, it writes all Java fields to native memory before the call and updates them based on native memory afterwards.

EDIT

According to the header file, DeviceType should use NativeLong; your declaration will fail to run properly on any 64-bit system other than windows.

Make sure your library is using the stdcall calling convention (nominally that means implement the StdCallLibrary interface).

It also seems that you're providing an invalid ("65535") value for the DeviceType; check that the value returned in NumDevices[0] is not zero.

You should also check the return value; if it's zero, then you shouldn't expect anything to be written to your structure.



标签: java dll jna