JNA updateStructureByReference()的麻烦 [英] JNA updateStructureByReference() trouble
问题描述
这是我第一次使用JNA。我想要做的是在DLL中调用一个函数(C代码) - >(unsigned long DeviceTypes,NeoDevice * pNeoDevice,int * pNumDevices)...(JNA form) - >
(int, NeoDevice.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 {
};
}
我试图使用'updateStrucureByReference(类类型,对象,指向对象的指针)'更新字段。我不相信我的类型参数是正确的还是正确的?我在做别的事吗?任何输入将不胜感激。
当我尝试打印出他们看起来都是零的字段。
在我的主类中,我有
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();
对象serialN = myDeviceByRef.readField(SerialNumber);
NeoDevice.ByReference myDeviceBy = Structure.updateStructureByReference(NeoDevice.ByReference,myDeviceByRef,myDeviceByRef.getPointer());
事实上, Structure.updateStructureByReference
不是一个公共功能,应该是你第一个表示你做错了事情。 >
通过声明结构字段 volatile
,您告诉JNA避免将其值复制到本机内存,这通常会自动执行在本机函数调用之前。这只是一个问题,如果你打算将Java字段中的值传递给本机函数;如果您只想回读结果, volatile
无关紧要。
如果您的 icsneoFindNeoDevices
被声明为采用一个 NeoDevice
实例作为其第二个参数(而不是一个指针),那么JNA将自动同步结构字段正确(它将在函数调用后更新Java字段)。当JNA遇到 Structure
参数时,它会在调用之前将所有Java字段写入本地内存,然后再根据本地内存进行更新。
编辑
根据头文件, DeviceType
应该使用 NativeLong
;您的声明将无法在Windows以外的任何64位系统上正常运行。
确保您的库正在使用 stdcall
调用约定(名义上这意味着实现 StdCallLibrary
接口)。
也似乎你为DeviceType提供无效(65535)值;检查 NumDevices [0]
中返回的值不为零。
您还应检查返回值;如果是零,那么你不应该指望任何东西写入你的结构。
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());
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.
这篇关于JNA updateStructureByReference()的麻烦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!