JNA updateStructureByReference()的麻烦 [英] JNA updateStructureByReference() trouble

查看:1854
本文介绍了JNA updateStructureByReference()的麻烦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一次使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆