2

I have a .h file that I need to translate into Delphi, to call a DLL interface that is written in C/C++.

In 32bit, everything goes well, I can use the DLL with a Delphi app with no issue.

In 64bit, it does not work very well.

I did not write this DLL interface, it comes from a third party that does hardware.

namespace gXusb {
    
typedef int            INTEGER;
typedef short          INT16;
typedef unsigned       CARDINAL;
typedef unsigned char  CARD8;
typedef float          REAL;
typedef double         LONGREAL;
typedef char           CHAR;
typedef unsigned char  BOOLEAN;
typedef void *         ADDRESS;
    
struct CCamera;
    
extern "C" EXPORT_ void __cdecl Enumerate( void (__cdecl *CallbackProc)(CARDINAL) );
extern "C" EXPORT_ CCamera *__cdecl Initialize( CARDINAL Id );

Is Cardinal still 32bit unsigned under 64bit?

I'm not very sure about this way of declaring this function type and what it does with 64bit compilation:

void (__cdecl *CallbackProc)(CARDINAL)

It looks a bit cumbersome.

What puzzles me is this:

typedef unsigned       CARDINAL;

I have figured out this is 32bit for a 32bit DLL, but did it stay 32bit under a 64bit DLL?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Does this answer your question? [What does the C++ standard state the size of int, long type to be?](https://stackoverflow.com/questions/589575/what-does-the-c-standard-state-the-size-of-int-long-type-to-be) – GSerg Jun 12 '21 at 17:18
  • 1
    Are you trying to mix-and-match 32-bit and 64-bit exe and DLL(s) because this can't work? – Richard Critten Jun 12 '21 at 17:24
  • This DLL interface is a bit strange and I did not write this. – user1816813 Jun 12 '21 at 23:21
  • "Are you trying to mix-and-match 32-bit and 64-bit exe and DLL(s) because this can't work? – " -> No my exe is 64 bits and the DLL is also 64 bits – user1816813 Jun 13 '21 at 01:41
  • `unsigned` means `unsigned int`, which has the same size as `int` (which is 32 bits for most compilers). – Olivier Jun 13 '21 at 07:14

1 Answers1

0

Something like the following should work fine in both 32bit and 64bit:

unit gXusb;

interface

type
  // prefixing types that Delphi already declares...
  _INTEGER = Int32;
  _INT16 = Int16;
  _CARDINAL = UInt32;
  CARD8 = UInt8;
  _REAL = Single;
  LONGREAL = Double;
  _CHAR = AnsiChar;
  _BOOLEAN = ByteBool;
  ADDRESS = Pointer;

  CCamera = record end;
  PCCamera = ^CCamera;

  UsbEnumCallback = procedure(Param: _CARDINAL); cdecl;

procedure Enumerate(Cb: UsbEnumCallback); cdecl;
function Initialize(Id: _CARDINAL): PCCamera; cdecl;

implementation

const
  TheDLLName = 'the.dll';

procedure Enumerate; external TheDLLName;
function Initialize; external TheDLLName;

end.

Personally, I would just get rid of any type aliases that are not strictly necessary, use native Delphi types were appropriate, eg:

unit gXusb;

interface

type
  CARD8 = UInt8;

  CCamera = record end;
  PCCamera = ^CCamera;

  UsbEnumCallback = procedure(Param: UInt32); cdecl;

procedure Enumerate(Cb: UsbEnumCallback); cdecl;
function Initialize(Id: UInt32): PCCamera; cdecl;

implementation

const
  TheDLLName = 'the.dll';

procedure Enumerate; external TheDLLName;
function Initialize; external TheDLLName;

end.
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I was told that Windows use only one single calling convention in the 64bit mode -- _stdcall, regardless of modifiers (_cdecl etc. are ignored in 64bit Windows). I think delphi simply ignore them ? – user1816813 Jun 16 '21 at 12:19
  • Yes, there is a [single calling convention on 64bit](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160), but it is not `stdcall`. – Remy Lebeau Jun 16 '21 at 15:05