2012-08-27 64 views
4

我有在回調功能的程序崩潰(Delphi編寫的6)的問題。該函數中的函數沒有任何錯誤,因爲它在其他地方使用,並且我有一條跟蹤語句作爲該函數的最後一行獲取輸出。我想知道在我的界面中是否有錯誤。從C頭文件的提取物是...C至Delphi的翻譯

/* 
#ifdef SSLCLIENT_EXPORTS 
    #define SSLCLIENT_API __declspec(dllexport) 
#else 
    #define SSLCLIENT_API __declspec(dllimport) 
#endif 
*/ 
#define SSLCLIENT_API 
#define CDR_EXPORT CALLBACK 

typedef int CDRHANDLE; 
// The definition of preceding call back functions is as follows: 
#define CDR_PRORESS_CONTINUE 0 
#define CDR_CANCEL_CONNECTION -1 

#define CONNECTION_TERMINATED  1 
#define CONNECTION_CLOSED   2 

#ifdef __cplusplus 
//extern "C" { 
#endif 

typedef int (CDR_EXPORT *RECEIVEINGFUNC) 
(
    char *callData, 
    void *applicationData 
); 

SSLCLIENT_API CDRHANDLE CDR_EXPORT CdrOpenConnection 
(
    char    *IPAddressOrMachineName, 
    char    *usernameOfCDRUserGroup, 
    char    *password, 
    RECEIVEINGFUNC CDRRecord, 
    STOPFUNC   CDRStop, 
    void    *applicationData 
); 


#ifdef __cplusplus 
//} // extern "C" 
#endif 
#endif 

,我用Drbobs程序以生成Delphi源賦予...

type 
    RECEIVEINGFUNC = function(CallData: PChar; ApplicationData: Pointer): integer; 
    STOPFUNC = procedure(StopReason: integer; ApplicationData: Pointer); 

(* = INT (CDR_EXPORT*RECEIVEINGFUNC) (CHAR*CALLDATA, VOID*APPLICATIONDATA); 
type 
    = VOID (CDR_EXPORT*STOPFUNC) (INT STOPREASON, VOID*APPLICATIONDATA); 
*) 

var 
    CdrOpenConnection: function(IPAddressOrMachineName: PChar; 
           usernameOfCDRUserGroup: PChar; 
           password: PChar; 
           CDRRecord: RECEIVEINGFUNC; 
           CDRStop: STOPFUNC; 
           applicationData: Pointer): CDRHANDLE cdecl {$IFDEF WIN32} stdcall {$ENDIF}; 

和我有功能

function DoCdrRecord1(CallData: PChar; ApplicationData: Pointer): integer; 
begin 
    try 
    // do stuff... 
    trace('DoCdrRecord1::back from _HndlCdrRec'); 
    except 
    on e: exception do 
    begin 
     trace('DoCdrRecord1::exception -> ' + e.message); 
    end; 
    end 
end; 

我的問題是...

  1. 做上面的Delphi declar ation看起來正確嗎?
  2. 編譯程序時應該包括WIN32嗎?

我不知所措的程序是怎麼回事錯在何處。任何幫助不勝感激。

+0

FreePascal也有一個h2pas轉換器。我懷疑它會更現代一些。我想你也會用這個工具轉換你的頭文件並比較結果。這可能會突出陰暗的角落。 –

+0

C頭到Pascal文件轉換器都不會完美工作,因爲它們不是C編譯器。他們做大部分解析,但總是需要手動干預(尤其是因爲大多數C代碼嚴重依賴宏擴展)。 –

回答

4

你缺少調用約定。

RECEIVEINGFUNC被定義爲CDR_EXPORT,以及高一點了,我們看到:

#define CDR_EXPORT CALLBACK 

而且CALLBACK needs to be defined in Delphi imports as stdcall;.所以解決您的功能像這樣,它應該工作:

function DoCdrRecord1(CallData: PChar; ApplicationData: Pointer): integer; stdcall; 
+1

CALLBACK通常是STDCALL,而不是cdecl(windef.h:#define CALLBACK __stdcall) – MBo

+0

啊,你說得對。對不起,這已經很晚了。現在修復。非常感謝 –

+0

,會給你一個機會。 – samanne

4

1.執行上面的Delphi聲明看起來正確嗎?

他們是正確的,但有一個例外。這兩個回調函數類型具有不正確的調用約定。在C代碼中,回調函數類型用CDR_EXPORT聲明,而CDR_EXPORT又定義爲CALLBACK。這又是在Windows頭文件和__stdcall中定義的。所以你的Delphi函數類型需要匹配。

RECEIVEINGFUNC = function(CallData: PChar; 
    ApplicationData: Pointer): integer; stdcall; 
STOPFUNC = procedure(StopReason: integer; 
    ApplicationData: Pointer); stdcall; 

這是翻譯中唯一的錯誤。

2.編譯 程序時是否應該包括WIN32?

我猜你的意思是,定義而不是包括。這裏沒有什麼可做的。 WIN32條件由Delphi 6編譯器定義。你不需要定義它。

我期待IFDEF有因爲鮑勃博士的轉換器最初瞄準的16位的Delphi 1和16位Windows,Windows默認調用約定是長期被遺忘的Pascal調用約定。 IFDEF現在是一個遺蹟,你可以刪除它。但保持stdcall,自然。

我從來沒有帶自動翻譯頭非常高興。就我個人而言,我認爲你可能會更好地親手做。

+0

非常感謝,會給你一個鏡頭。 – samanne