我正在尝试使用以下java代码使用JNA实现从Delphi到Java的简单回调:
package jnaapp;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Callback;
public class JnaAppTest {
public interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary((Platform.isWindows() ? "helloDelphi" : "c"),
CLibrary.class);
public interface eventCallback extends Callback {
public void callback(int id);
}
boolean setCallback(eventCallback callback);
boolean TestFunction(byte[] text, int length);
}
public static void main(String[] args) throws Exception{
byte[] text = new byte[100];
CLibrary.eventCallback callback = new CLibrary.eventCallback(){
public void callback(int id){
System.out.println("I was called with: "+id);
}
};
System.out.println(CLibrary.INSTANCE.setCallback(callback));
System.out.println(CLibrary.INSTANCE.TestFunction(text, 100));
System.out.println(Native.toString(text));
}
}
相应的Delphi代码如下:
Library helloDelphi;
uses
SysUtils,
Classes;
{$R *.res}
type TCallback = procedure(val: Integer); stdcall;
var
cb : TCallback;
function setCallback(callBack : TCallback) : WordBool; stdcall; export;
begin
cb := callBack;
Result := True;
end;
function TestFunction(stringBuffer : PAnsiChar; bufferSize : integer) : WordBool; stdcall; export
var s : string;
begin
s := 'Hello World 2';
StrLCopy(stringBuffer, PAnsiChar(s), bufferSize-1);
cb(bufferSize);
Result := True;
end;
exports TestFunction;
exports setCallback;
begin
end.
当从Delphi调用回调时,这会导致VM崩溃。如果我从Testfunction中删除回调,一切正常!谢谢你的帮助!
答案 0 :(得分:4)
Delphi使用stdcall
调用约定,因此您需要使用StdCallLibrary
,而不是Library
。错误的约定会导致崩溃,因为被调用的函数将期望使用与调用代码不同的堆栈布局。
您还需要使用StdCallCallback
而不是Callback
。