0

我有这个java测试

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

 }
}

它调用一个 Delphi DLL。如果将参数作为 var 在 Delphi 中,Java 会崩溃。否则它们是只读的。

我希望 GetDataRecord 在 RecordNum 等中返回数据。如何在 java 中执行此操作?

4

1 回答 1

3

您需要将参数声明为特殊类型,以传达它们通过引用传递的事实。所以如果Delphi参数是这样的:

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

文档中详细介绍了这一切:

使用 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() 之外,Pointer 类还提供了许多访问器方法,它们有效地用作内存上的类型转换。

类型安全指针可以通过派生自 PointerType 类来声明。

于 2013-06-29T14:46:02.557 回答