[英]Call DLL written in Delphi from Java
我有一个用 Delphi 10.4 编写的简单 DLL。 When I call the DLL from another Delphi application, everything works 100%, but when I call the same DLL from a Java application (using JNA) I get strange results.
我最初声明了 PChar 类型的 DLL 输入参数。 当我从 Java 应用程序调用 DLL 时,我的 DLL 中出现了有趣的字符。 我将其更改为 ShortString,但随后我丢失了 DLL 中字符串的第一个字符。 我可能需要在 Java 中进行一些数据类型转换,但我不知道是什么。 有人可以帮忙吗?
这是 Delphi 中的示例 DLL 来演示:
procedure TestDataTypes(PCharVar: PChar; ShortStringVar: ShortString); stdcall;
begin
ShowMessage('PChar: ' + PCharVar + #13#10 +
'ShortString: ' + ShortStringVar);
end;
exports
TestDataTypes;
从 Delphi 调用 DLL 的代码:
procedure TestDataTypes(PCharVar: PChar; ShortStringVar: ShortString); stdcall; external 'TestDataType.dll';
...
TestDataTypes(PChar('PChar Value'), 'ShortString Value');
从 Java 调用 DLL 的代码:
INSTANCE.TestDataTypes("Java PChar Value", "Java ShortString Value");
结果:顶部是从 Delphi 调用 DLL 时,底部是从 Java 调用时:
一些反馈:我将 Delphi 中的数据类型更改为 PAnsiChar,它可以在我的本地电脑上运行。 部署后,它可以在某些客户端机器上工作,但不能在其他机器上工作。 当我从我的 Java 应用程序调用 DLL 时得到的错误是“无效的 memory 访问”。 我已经在我的 DLL 中添加了日志记录,它似乎甚至没有进入 DLL....
Delphi 代码:
function HasCOMConnection(COMServerName: PAnsiChar): Boolean; stdcall;
begin
WriteLog('HasCOMConnection: 64-Bit DLL entered');
Result := HasConnection(COMServerName);
end;
Java 致电:
private interface IPMOProcessLabResult extends com.sun.jna.Library {
boolean HasCOMConnection(String COMServerName);
}
private boolean canConnectToCOMServer() {
try {
IPMOProcessLabResult lib = (IPMOProcessLabResult) Native.loadLibrary(config.libraryName, IPMOProcessLabResult.class);
return lib.HasCOMConnection(config.comServerName);
}
catch (Exception ex) {
new AppendLog(new Date(), this.getClass() + "\t" + ex.getClass() + "\t" + "Exception while trying to connect to COMServer: " + ex.getMessage(), "debug");
return false;
}
}
PChar
只是一个别名,在 2009 年使用 Delphi 更改为PWideChar
(假设标准字符串和字符类型更改为Unicode
)。 所以现在每个字符都使用 2 个字节。
因此,为了使您的 DLL 正常工作,您应该将PChar
更改为PAnsiChar
。
或者您必须对您的 Java 应用程序进行一些更改,以便它使用一些两字节字符类型。 但是我没有 Java 的经验,所以我帮不了你。
忘记短字符串,这种类型与其他语言不兼容!
有关如何使用和不使用 DLL 的更多参考信息,请参阅此站点。
ShortString
是一个旧的 Delphi 类型,它包含一个 ANSI 字符串并将长度存储在第一个字节中。 你不应该使用它。
PChar
在最新版本的 Delphi 中是PWideChar
的别名。
您正在使用JNA从 Java 调用本机代码。
Java String
在内部使用 UTF-16。
JNA 使用以下规则:
String
转换为PAnsiChar
WString
被转换为PWideChar
因此,如果您想将 Unicode 字符串传递给 DLL,您应该像这样声明 Java 方法:
public void TestString(WString text);
在 Delphi 中:
procedure TestString(Text: PChar); stdcall;
begin
ShowMessage(Text);
end;
并像这样调用 function:
INSTANCE.TestString(new WString("A Unicode string"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.