2013-06-29 23 views
0

我有這樣的Java測試如何獲得一個java JNA調用到DLL以獲取參數中返回的數據?

package ftct; 

import com.sun.jna.Library; 
import com.sun.jna.Native; 
import com.sun.jna.Platform; 
import com.sun.jna.win32.StdCallLibrary; 
import java.util.Date; 

public class LibFTCT { 


public LibFTCT() { 
} 
public interface LibFTCTLib extends StdCallLibrary { 
      LibFTCTLib INSTANCE = (LibFTCTLib) Native.loadLibrary(
      "FTCTLib", LibFTCTLib.class); 
     int a(int x); 
     int DoCommand(int Command, int Param); 
    int GetDataRecord(int RecordNum, int StreamNum, Date ReadingTime, 
    double AIN1, double AIN2, double AIN3, double AIN4); 

} 
} 

它調用DLL德爾福。如果在Delphi中將參數設置爲var,那麼Java會崩潰。否則,它們是隻讀的。

我想讓GetDataRecord在RecordNum等中返回數據如何在java中執行此操作?

+1

我不是JNA專家,但由於var參數是引用參數,我不認爲事物的Java方面可以聲明和使用原語。 –

+0

你希望會發生什麼Date參數? –

+0

@David我發現了一些代碼,建議使用Date date = new Date((long)(ReadingTimeRef.getValue()* 1000.0)); ReadingRecords [RecNo-1] .ReadingTime = date;但我還沒有測試過。 –

回答

3

您需要將參數聲明爲特殊類型,這些類型表示它們通過引用傳遞的事實。因此,如果德爾福參數是這樣的:

procedure Foo(var i: Integer; var d: Double); 

你會映射到Java函數是這樣的:

void Foo(IntByReference i, DoubleByReference d); 

,並調用函數:

IntByReference iref = new IntByReference(); 
DoubleByReference dref = new DoubleByReference(); 
INSTANCE.Foo(iref, dref); 
int i = iref.getValue(); 
double d = dref.getValue(): 

這是所有在documentation中有詳細說明:

使用ByReference參數

當一個函數接受一個指針到類型參數,你可以使用一個 的ByReference類型捕捉返回的值,或繼承你 自己。例如:

// Original C declaration 
void allocate_buffer(char **bufp, int* lenp); 

// Equivalent JNA mapping 
void allocate_buffer(PointerByReference bufp, IntByReference lenp); 

// Usage 
PointerByReference pref = new PointerByReference(); 
IntByReference iref = new IntByReference(); 
lib.allocate_buffer(pref, iref); 
Pointer p = pref.getValue(); 
byte[] buffer = p.getByteArray(0, iref.getValue()); 

或者,可以使用Java陣列與 所需類型的單個元件,但ByReference公約更好傳送代碼的意圖 。除了getByteArray()之外,指針類還提供了一些訪問方法 ,這些getByteArray()有效地用作類型轉換 到內存中。

類型安全指針可以通過從PointerType 類派生來聲明。

相關問題