我正在从 Java 程序的 Delphi 编译 *.so 文件中调用函数。经过一些研究, JNA似乎是他要走的路。在深入研究一些复杂的 Delphi 代码之前,我正在尝试使用一些“Hello World”代码,但在获取 Delphi 函数返回的字符串时遇到了麻烦。
Delphi 代码(helloworld.pp):
library HelloWorldLib;
function HelloWorld(const myString: string): string; stdcall;
begin
WriteLn(myString);
Result := myString;
end;
exports HelloWorld;
begin
end.
我使用“ fpc -Mdelphi helloworld.pp ”从命令行编译它,生成libhelloworld.so。
现在我的Java类:
import com.sun.jna.Library;
import com.sun.jna.Native;
public class HelloWorld {
public interface HelloWorldLibrary extends Library {
HelloWorldLibrary INSTANCE = (HelloWorldLibrary) Native.loadLibrary("/full/path/to/libhelloworld.so", HelloWorldLibrary.class);
String HelloWorld(String test);
}
public static void main(String[] args) {
System.out.println(HelloWorldLibrary.INSTANCE.HelloWorld("QWERTYUIOP"));
}
}
但是,当我运行此 Java 代码时,我得到:
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f810318add2, pid=4088, tid=140192489072384
#
# JRE version: 7.0_10-b18
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libhelloworld.so+0xbdd2] HelloWorld+0x6fea
请注意,如果我更改我的 Delphi 方法(和相关的 Java 接口)以返回一个硬编码的整数,一切都会很好:我传递的字符串被打印出来,并且我得到了预期的 int。
奇怪的是,如果 Delphi 方法返回一个字符,我必须将我的 JNA 代理编写为返回一个字节并手动将其转换为字符(如果我将我的接口声明为返回一个字符,它会打印出一个垃圾字符)。
知道这里出了什么问题吗?
仅供参考,我使用的是 64 位 Ubuntu 12.04,使用 Sun JDK 1.7.0_10-b18、JNA 3.5.1 和 Free Pascal Compiler 版本 2.4.4-3.1。