【发布时间】:2014-11-11 11:35:46
【问题描述】:
我正在使用 Java JNA 库来调用我创建的 Delphi DLL。我正在使用的 Delphi 函数返回一个类型,它是一个 PAnsiChar 数组。我遇到的问题是,当我尝试在 Java 中调用该函数时,它给了我一个java.lang.Error: Invalid memory access。
我的 Delphi 代码在这里:
function doTest(inputStatement: PAnsiChar): TDynamicAnsiCharArray; stdcall;
begin
SetLength(result, 3);
result[0] := 'Line 1';
result[1] := 'Line 2';
result[2] := 'Line 3';
end;
我的 Java 代码在这里:
public interface CLib extends StdCallLibrary {
CLib INSTANCE = (CLib) Native.loadLibrary("DatabaseLibrary", CLib.class);
public String[] doTest(String input);
}
public Main() {
String[] dllOut = CLib.INSTANCE.doTest("Test?");
for(int i = 0; i < dllOut.length; i++){
System.out.println(dllOut[i]);
}
}
完整的 Java 错误在这里:
Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokePointer(Native Method)
at com.sun.jna.Function.invokePointer(Function.java:470)
at com.sun.jna.Function.invoke(Function.java:430)
at com.sun.jna.Function.invoke(Function.java:315)
at com.sun.jna.Library$Handler.invoke(Library.java:212)
at com.sun.proxy.$Proxy0.doTest(Unknown Source)
at Main.<init>(Main.java:17)
at Main.main(Main.java:25)
第 17 行是带有 String[] 定义的行。
我有一种感觉,这种方式根本行不通,但我希望确实有办法。
【问题讨论】:
-
你不能这样。您不能跨互操作边界返回 Delphi 字符串。你也不能返回动态数组。你需要找到另一种方法。通常这将涉及调用者分配内存。
-
也许stackoverflow.com/q/10158582/80901 有帮助,它使用了Pointer JNA 类
-
只是指出这一点,但我能够将单个
PAnsiChar从 dll 传递回 Java。 -
我已经查看了关于该主题的几乎所有 Stack Overflow 问题,但我似乎找不到任何可以正确显示如何在这两者之间以某种方式传递数据数组的任何问题。根据我所见,您可以在 Java 中声明一个数组,然后将其作为参数传递给 Delphi,Delphi 填充它并将其传回给 Java。但是,我找不到如何将这些数据实际获取到 java 变量中
-
如果你想解决这个问题,这取决于你,但你可能做错了。您如何确保分配的缓冲区超出函数的生命周期?调用者如何释放函数分配的内存?
标签: java arrays delphi dll jna