4
votes

I have a dll that is written in C. My delphi wrapper is calling functions from c++ dll.

This is C++ code:

typedef enum EFTDeviceControlAction
{
        EFT_DCA_CR_CARD_RETRACT = 0x01,
        EFT_DCA_CR_CARD_REPOSITION = 0x02,
        EFT_DCA_CR_SHUTTER_OPEN = 0x03,
        EFT_DCA_CR_SHUTTER_CLOSE = 0x04,
        EFT_DCA_CR_CARD_EJECT = 0x05,
}

typedef enum EFT_PrintOptions {
        poPrintState = 0,
        poPrintFirst = 1,
        poPrintSubsequent = 2,
        poPrintFinal = 3,
        poPrintAbort = 9
} EFT_PrintOptions;


typedef void * EFT_HANDLE;

int EFT_CreateSession(EFT_HANDLE * h);
int EFT_DestroySession(EFT_HANDLE h);
int EFT_ReadProperty(EFT_HANDLE h, int table, int index, char * pValue, unsigned int maxLength);
int EFT_WriteProperty(EFT_HANDLE h, int table, int index, char * pValue);
...

And this is delphi code :

EFTDeviceControlAction = (
        EFT_DCA_CR_CARD_RETRACT = $01,
        EFT_DCA_CR_CARD_REPOSITION = $02,
        EFT_DCA_CR_SHUTTER_OPEN = $03,
        EFT_DCA_CR_SHUTTER_CLOSE = $04,
        EFT_DCA_CR_CARD_EJECT = $05,
);

EFT_PrintOptions = (
        poPrintState = 0,
        poPrintFirst = 1,
        poPrintSubsequent = 2,
        poPrintFinal = 3,
        poPrintAbort = 9
);

EFT_HANDLE = pointer;

function EFT_CreateSession(var h: EFT_HANDLE): Integer; stdcall; external 'api.dll';
function EFT_DestroySession(h: EFT_HANDLE): Integer; stdcall; external 'api.dll';
function EFT_ReadProperty(h: EFT_HANDLE; table: Integer; index: Integer; pValue: PChar; maxLength: Cardinal): Integer; stdcall; external 'api.dll';
function EFT_WriteProperty(h: EFT_HANDLE; table: Integer; index: Integer; pValue: PChar): Integer; stdcall; external 'api.dll';

Problem that I have is the line (C++)

typedef void * EFT_HANDLE 

How is this line defined in Delphi? Is this a pointer, procedure ??? and what value do I use for parameter when I call function?

For every call I get Access violation at address 0040537B in module

1

1 Answers

3
votes
typedef void * EFT_HANDLE;

The name of the declared type is EFT_HANDLE and it is an alias for void*. And void* is simply an untyped pointer.

So, in Delphi you define it like this:

type
  EFT_HANDLE = Pointer;

Which is exactly what you already did.

The rest of your translations look basically quite reasonable. I have these comments:

  1. Are you sure the calling convention is stdcall? The C++ code you show does not specify a calling convention, and that invariably means cdecl.
  2. Use PAnsiChar rather than PChar so that your code is correct on Unicode Delphi as well as old non-Unicode Delphi.

The obvious place for an access violation is the null-terminated string. It would be helpful to see the code that you have which calls EFT_ReadProperty. It will need to look like this:

var
  prop: AnsiString;
....
SetLength(prop, 128); // for example, not sure what value is needed here
retval := EFT_ReadProperty(handle, index, PAnsiChar(prop), Length(prop)+1);
// the +1 is for the null-terminator, but the library will specify exactly 
// how that is handled and it could equally be that the +1 is omitted