Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C to Delphi Translation

Tags:

c

header

delphi

I have a problem with a program crashing (written in Delphi 6) in a callback function. There is nothing wrong in that function in that function as it is used elsewhere, and I have a trace statement as the last line in that function which gets output. I am wondering if there is something wrong in the interface I have. An extract from the C header file is...

/*
#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

and I used Drbobs programs to generate a Delphi source which gives...

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};

and I have function

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;

My question are...

  1. Do the above Delphi declarations look correct?
  2. Should I be including WIN32 when compiling the program?

I am at a loss as to where the program is going wrong. Any help greatly appreciated.

like image 703
samanne Avatar asked Feb 20 '23 09:02

samanne


1 Answers

1. Do the above Delphi declarations look correct?

They are correct, with one exception. The two callback function types have the incorrect calling convention. In the C code the callback function types are declared with CDR_EXPORT which in turn is defined as CALLBACK. That in turn is defined in the Windows header files and __stdcall. So your Delphi function types need to match.

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

This is the only error in the translation.

2. Should I be including WIN32 when compiling the program?

I guess you mean, defining rather than including. There's nothing to do here. The WIN32 conditional is defined by the Delphi 6 compiler. You don't need to define it.

I expect that IFDEF is there because Dr. Bob's converter originally targeted 16 bit Delphi 1. And on 16 bit Windows, the default Windows calling convention was the long-forgotten pascal calling convention. That IFDEF is now a relic and you can remove it. But keep the stdcall, naturally.

I've never been terribly happy with automatic header translators. Personally I think you might be better doing it by hand.

like image 143
David Heffernan Avatar answered Feb 28 '23 08:02

David Heffernan