tags:

views:

281

answers:

3

I have a third-party (Win32) DLL, written in C, that exposes the following interface:

DLL_EXPORT typedef enum
{
  DEVICE_PCI = 1,
  DEVICE_USB = 2
} DeviceType;

DLL_EXPORT int DeviceStatus(DeviceType kind);

I wish to call it from Delphi.

How do I get access to the DeviceType constants in my Delphi code? Or, if I should just use the values 1 and 2 directly, what Delphi type should I use for the "DeviceType kind" parameters? Integer? Word?

+2  A: 

Default underlying type for enum in C++ is int (unsigned 32 bits). You need to define the same parameter type in Delphi. Regarding enumerated values, you can use hard-coded 1 and 2 values to call this function from Delphi, or use any other Delphi language feature (enum? constant? I don't know this language) which gives the same result.

Alex Farber
If you want to use it as an enum you must set the enumsize to 4 using the {$MINENUMSIZE 4} directive
Remko
+2  A: 

The usual way to declare the interface from an external DLL in C is to expose its interface in a .H header file. Then, to access the DLL from C the .H header file has to be #included in the C source code.

Translated to Delphi terms, you need to create a unit file that describes the same interface in pascal terms, translating the c syntax to pascal.

For your case, you would create a file such as...

unit xyzDevice;
{ XYZ device Delphi interface unit 
  translated from xyz.h by xxxxx --  Copyright (c) 2009 xxxxx
  Delphi API to libXYZ - The Free XYZ device library --- Copyright (C) 2006 yyyyy  }

interface

type
  TXyzDeviceType = integer;

const
  xyzDll = 'xyz.dll';
  XYZ_DEVICE_PCI = 1;
  XYZ_DEVICE_USB = 2;

function XyzDeviceStatus ( kind : TXyzDeviceType ) : integer; stdcall; 
   external xyzDLL; name 'DeviceStatus';

implementation
end.

And the you would declare it in the uses clause of your source code. And invoke the function this way:

uses xyzDevice;

...

  case XyzDeviceStatus(XYZ_DEVICE_USB) of ...
PA
+1  A: 

Sure, you can use Integer and pass constanst directly, but it is more safe to declare function with using usual enum type. It should be like this (note "MINENUMSIZE" directive):

{$MINENUMSIZE 4}

type
  TDeviceKind = (DEVICE_PCI = 1, DEVICE_USB = 2);

function DeviceStatus(kind: TDeviceKind): Integer; stdcall; // cdecl?
Alexander
Unfortunately this is wrong, as written `DEVICE_PCI` will equal 0, not 1. You need to insert a dummy like `DEVICE_UNKNOWN` for value 0, or give the value 1 to the first enum.
mghie
@mghie well spotted. The best way would be to use the ` type TDeviceKind =(DEVICE_PCI = 1, DEVICE_USB = 2)` syntax added in Delphi 6? See http://docwiki.embarcadero.com/RADStudio/en/Simple_Types#Enumerated_Types_with_Explicitly_Assigned_Ordinality
Gerry
Oops. I'm must be still sleeping. Fixed.
Alexander