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.
libhelloworld.soを生成する" fpc -Mdelphi helloworld.pp "を使用して、コマンド ラインからコンパイルします。
今私の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 メソッドが char を返す場合、バイトを返すように JNA プロキシを記述し、それを手動で char にキャストする必要があります (インターフェイスが char を返すと宣言すると、文字化けが出力されます)。
ここで何がうまくいかないのですか?
参考までに、Sun JDK 1.7.0_10-b18、JNA 3.5.1、および Free Pascal Compiler バージョン 2.4.4-3.1 を使用して、64 ビットの Ubuntu 12.04 を使用しています。