P/Invoke 回调函数指针的试验
有些API函数需要传进一个回调函数指针, 在.NET中可以传一个delegate过去, 不过.NET到底是如何辨别回调函数的调用约定呢? 虽然Window API的回调函数都是以stdcall来声明, 但也不代表所有的都是这样, 比如, 我写个比较离经判道的Win32代码:
library CBDll;
uses
SysUtils,
Classes;
{$R *.res}
type
TMyCallBackFunc1 = procedure (P1: Integer; P2: Integer); stdcall;
TMyCallBackFunc2 = procedure (P1: Integer; P2: Integer); pascal;
procedure DoCallBack1(Proc: TMyCallBackFunc1); stdcall;
begin
Proc(1, 2);
end;
procedure DoCallBack2(Proc: TMyCallBackFunc2); stdcall;
begin
Proc(1, 2);
end;
exports
DoCallBack1,
DoCallBack2;
begin
end.
然后在另一个.net项目中使用这个DLL
type
TMyCallBackFunc1 = procedure (P1: Integer; P2: Integer);
TMyCallBackFunc2 = procedure (P1: Integer; P2: Integer);
procedure DoCallBack1(Proc: TMyCallBackFunc1); external 'CBDll.dll';
procedure DoCallBack2(Proc: TMyCallBackFunc2); external 'CBDll.dll';
procedure CallBack1(P1: Integer; P2: Integer);
begin
ShowMessageFmt('%d, %d', [P1, P2]);
end;
procedure CallBack2(P1: Integer; P2: Integer);
begin
ShowMessageFmt('%d, %d', [P1, P2]);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
DoCallBack1(@CallBack1);
DoCallBack2(@CallBack2);
end;
DoCallBack1是使用调用约定为stdcall的回调函数指针, 而DoCallBack2使用pascal, 两种调用约定不同之处在于pascal的参数入栈顺序按语法声明顺序从左到右依次入栈, 而stdcall与之相反, 结果DoCallBack1弹出的消息是"1, 2", DoCallBack2弹出的消息是"2, 1", 可见.NET P/Invoke处理回调只处理了stdcall这一种类型
浙公网安备 33010602011771号