2013-06-27 40 views
0

這是我第一次使用JNA。我想要做的是調用一個DLL中的函數,它需要(C代碼) - >(無符號長DeviceTypes,NeoDevice * pNeoDevice,int * pNumDevices)...(JNA形式) - > (int,NeoDevice.getPointer (),int [] myInt) as params。函數應寫入結構的字段,我想查看更新的字段。JNA updateStructureByReference()麻煩

這裏是我的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(類類型,對象,指針對象)」更新的字段。我不相信我的'類類型'參數是正確的還是它?我在做別的事情嗎?任何投入將不勝感激。

當我試圖println他們看起來都是零仍然是領域。

在我的主類,我有

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

回答

0

事實上,Structure.updateStructureByReference不是公共職能應該是你做錯了什麼你的第一個跡象。

通過聲明結構字段volatile,您告訴JNA避免將它們的值複製到本機內存,通常在本機函數調用之前它會自動執行此操作。如果您打算將Java字段中的值傳遞給本機函數,這只是一個問題;如果你只想回讀結果,volatile並不重要。

如果您的icsneoFindNeoDevices被聲明爲以NeoDevice實例作爲其第二個參數(而不是指針),那麼JNA會自動同步結構字段(它將在函數調用後更新Java字段)。當JNA遇到Structure參數時,它會在調用之前將所有Java字段寫入本機內存,然後根據本機內存更新它們。

編輯

the header fileDeviceType應該使用NativeLong;您的聲明將無法在Windows以外的任何64位系統上正常運行。

確保您的庫正在使用stdcall調用約定(名義上表示實現StdCallLibrary接口)。

它似乎也提供了DeviceType無效(「65535」)值;檢查NumDevices[0]中返回的值是否不爲零。

您還應該檢查返回值;如果它爲零,那麼你不應該期望任何東西被寫入你的結構。

+0

感謝您的意見!我只對讀取BACK值有興趣。 沒有Structure.updateStructureByReference,在我調用該函數並嘗試查看字段值後,它們都是零。 我目前與結構.read()和結構.readField()爲了查看字段,但仍然有問題鬼混 –

+0

我沒有訪問的源代碼來修改參數,所以我被迫通過NeoDevice作爲指針 –

+0

只需在函數調用後刪除'volatile'並調用'Structure.read()'。 – technomage