Jacek
Jacek

Reputation: 59

callback c delphi

This is procedure which is defined in C++ application (exe HOST).

typedef struct _ RX_DATA_OBJ {
   UINT32     TIME;        
   UINT32     ID;    
   UINT8      LEN; 
   UINT8      DATA[8]; 
} RX_DATA_OBJ;

static void RX_DATA(UINT16 CNT, RX_DATA_OBJ *p_RX_DTATA_OBJ)

I need to call as callback above function in my DLL file written in Delphi.

I made the following declaration in Delphi for my DLL:

type
  TRX_DATA_OBJ = record
    time: UINT32;
    id:   UINT32;
    len:  UINT8;
    data: array [0..7] of UINT8;
  end;
  PRX_DATA_OBJ = ^TRX_DATA_OBJ;

RX_DATA = procedure(count:UINT16; RX_DATA_OBJ: PRX_DATA_OBJ ) of object;

var
  RX_DATA_out: TRX_DATA_OBJ;

In another procedure I get the pointer to the RX_DATA procedure in HOST. Now I call this callback in my DLL

procedure PUT_DATA;
begin
  RX_DATA_out.Time := 100;
  RX_DATA_out.id := $500;
  RX_DATA_out.len := 4;
  RX_DATA_out.data[0] := 1;
  RX_DATA_out.data[1] := 2;
  RX_DATA_out.data[2] := 3
  RX_DATA_out.data[3] := 4;
  RX_DATA_out.data[4] := 5;
  RX_DATA_out.data[5] := 6;
  RX_DATA_out.data[6] := 7;
  RX_DATA_out.data[7] := 8;

  RX_DATA(1, @RX_DATA_out); // RX_DATA_out is global variable defined.
end;

Callback is called correct but data passed in RX_DATA_out variable are not correct, it looks that pointer to RX_DATA_out variable is not pointing on this variable.

Can anybody say what can be wrong ?

Upvotes: 1

Views: 414

Answers (1)

David Heffernan
David Heffernan

Reputation: 613451

The C++ function type is a plain function, i.e. not a member function. But you have declared your version to be a method of object. That is a mismatch. You must remove of object.

You must also specify the calling convention. Most likely it will be cdecl. In Delphi, if the calling convention is not specified, then the register based Delphi fastcall convention, register is used. That's certainly wrong.

Finally, if the pointer to the struct can never be nil then it is more idiomatic to use a var parameter:

RX_DATA = procedure(count:UINT16; var RX_DATA_OBJ: TRX_DATA_OBJ); cdecl;

And obviously you'd have to change the calling code to match:

RX_DATA(1, RX_DATA_out);

Upvotes: 4

Related Questions