Reputation: 309
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...
I am at a loss as to where the program is going wrong. Any help greatly appreciated.
Upvotes: 4
Views: 546
Reputation: 84550
You're missing the calling convention.
RECEIVEINGFUNC
is defined as CDR_EXPORT
, and a little higher up we see:
#define CDR_EXPORT CALLBACK
And CALLBACK needs to be defined in Delphi imports as stdcall;
. So fix your function like so, and it should work:
function DoCdrRecord1(CallData: PChar; ApplicationData: Pointer): integer; stdcall;
Upvotes: 4
Reputation: 613013
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.
Upvotes: 4