2017-12-13 3 views
1
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); 

를 델파이 :변환하는 방법 C/C++ 콜백 functon이 같은 definetions 위의 변환

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 함수를 알고 있지만 콜백 나를 위해 새로운 기능입니다. 내 정의가 맞습니까?

+3

C 또는 C++의 언어는 무엇입니까? 그들은 다른 언어입니다. 예를 들어 C++에는 연산자 및 함수 오버로드가있어 이름 변환이 발생할 수 있습니다. –

+0

C 함수는 cdecl처럼 보입니다 –

답변

2

귀하의 델파이 번역에는 약간의 오류가 있습니다. 대신이 시도 :

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; 

코드에서 가장 중요한 차이점은 of object로 선언되지 TPaymentResultCallback입니다. 델파이 스타일의 메소드 포인터를 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마다 매번 다른 메소드를 호출해야합니다.

이 DLL은 사용자 정의 값을 콜백과 연관시키는 방법을 제공합니다. 그런 목적을 위해 별도의 DLL 함수가 없으면 DLL이 해당 옵션을 갖고 있지 않은 것처럼 보입니다. 실제 메서드 포인터를 해당 사용자 정의 값으로 간단히 전달할 수 있으며 비공개 콜백 함수가이를 직접 호출 할 수 있습니다. 전역 변수가 필요하지 않으므로 여러 이벤트가 병렬로 실행될 수 있습니다. 그러나 그것은 큰 IF입니다.

+0

그래서 어느 것을 선호합니까? 사용법은 어떻습니까? 죄송합니다, 혼란 스럽습니다. 고맙습니다. – ErkanK

+0

@ErkanK 당신이 선호하는 것은 당신에게 달려 있습니다. 자신의 상황에 맞는 것을 사용하십시오. –

+0

어제 당신의 정의를 시도했지만, 나는 내 문제를 해결할 수 없었다. 첫째로 나는 두 번째 defination를 시도했다. 항상 시작되는 myPaymentResultCallback 함수에서 "Access Vioaltion"오류가 발생합니다. 그래서 그것은 내 문제를 해결하지 못했습니다. 하지만이 defination 사랑 :) :) 첫 번째 defination은 항상 디버거 "변수가 필요합니다"라고 말했다. 그래서이 상황에 대한 내 잘못은 무엇입니까 – ErkanK

관련 문제