typedef void (*onPaymentResultCallback) (int result);
DLL_EXPORT int AR_payment_item_credit(const char *terminal_no, const char *description, double amount, enum currency_id cid, int receiptid,
onPaymentResultCallback cb);
我将以上定义转换为:
TonPaymentResultCallback = procedure(result:LongInt) of object;
function AR_payment_item_credit(HInst:THandle; const TerminalNo:PAnsiChar; const Description:PAnsiChar; Amount:Double; CurrencyId:LongInt;
RecepitID:LongInt; onPaymentResultCallback:tonPaymentResultCallback):LongInt;
var
MyFunct: function (const TerminalNo:PAnsiChar; const Description:PAnsiChar; Amount:Double; CurrencyId:LongInt;
RecepitID:LongInt; onPaymentResultCallback:tonPaymentResultCallback): LongInt; cdecl;
begin
Result := 0;
MyFunct:=GetProcAddress(HInst,'AR_payment_item_credit');
if Assigned(MyFunct) then
Result := MyFunct(TerminalNo, Description, Amount, CurrencyId, RecepitID,onPaymentResultCallback);
end;
我知道C / C ++ dll函数转换为Delphi,但回调对我来说是新的。 我的定义是否正确?
答案 0 :(得分:3)
您的Delphi翻译中存在一些错误。试试这个:
type
TPaymentResultCallback = procedure(AResult: Integer); cdecl;
function ARPaymentItemCredit(HInst: THandle; const TerminalNo: PAnsiChar;
const Description: PAnsiChar; Amount: Double; CurrencyID: Integer;
ReceiptID: Integer; onPaymentResult: TPaymentResultCallback): Integer;
var
MyFunct: function(const TerminalNo: PAnsiChar; const Description: PAnsiChar;
Amount: Double; CurrencyID: Integer; ReceiptID: Integer;
onPaymentResult: TPaymentResultCallback): Integer; cdecl;
begin
@MyFunct := GetProcAddress(HInst, 'AR_payment_item_credit');
if Assigned(MyFunct) then
Result := MyFunct(TerminalNo, Description, Amount, CurrencyID, ReceiptID, onPaymentResult)
else
Result := 0;
end;
与您的代码最重要的区别是TPaymentResultCallback
未声明为of object
。您不能将Delphi样式的方法指针用作C样式的函数指针,这意味着您不能使用非静态类方法进行DLL回调,至少在此示例中。
但是有一个简单的解决方法 - 将所需的方法指针存储在全局变量中,然后使用私有回调函数来调用它,例如:
type
TPaymentResultEvent = procedure(AResult: Integer) of object;
var
gOnPaymentResult: TPaymentResultEvent;
procedure myPaymentResultCallback(AResult: Integer); cdecl;
begin
if Assigned(gOnPaymentResult) then
gOnPaymentResult(AResult);
end;
function ARPaymentItemCredit(HInst: THandle; const TerminalNo: PAnsiChar;
const Description: PAnsiChar; Amount: Double; CurrencyID: Integer;
ReceiptID: Integer; onPaymentResult: TPaymentResultEvent): Integer;
type
TPaymentResultCallback = procedure(AResult: Integer); cdecl;
var
MyFunct: function(const TerminalNo: PAnsiChar; const Description: PAnsiChar;
Amount: Double; CurrencyID: Integer; ReceiptID: Integer;
onPaymentResult: TPaymentResultCallback): Integer; cdecl;
begin
@MyFunct := GetProcAddress(HInst, 'AR_payment_item_credit');
if Assigned(MyFunct) then
begin
gOnPaymentResult := onPaymentResult;
Result := MyFunct(TerminalNo, Description, Amount, CurrencyID, ReceiptID, @myPaymentResultCallback)
end
else
Result := 0;
end;
毋庸置疑,如果您需要同时调用ARPaymentItemCredit()
的多个类,这将无效。因此,每次都需要DLL调用不同的方法。
IF DLL提供了一种将用户定义的值与回调相关联的方法(并且您的示例似乎没有该选项,除非为此目的有单独的DLL函数),变得更容易您可以简单地将(指针)实际方法指针作为该用户定义的值传递,然后您的私有回调函数可以直接调用它。不需要全局变量,使其可以重复并行运行多个事件。但这是一个很大的 IF 。