Java回调从Delphi使用JNA崩溃虚拟机



我试图实现一个简单的回调从Delphi到Java使用JNA使用以下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中删除回调,一切都可以正常工作!谢谢你的帮助!

Delphi使用stdcall调用约定,因此您需要使用StdCallLibrary,而不是Library。错误的约定将导致崩溃,因为被调用的函数将期望使用与调用代码不同的堆栈布局。

您还需要使用StdCallCallback而不是Callback

最新更新