1. Anatomy of a C Header
## to do
2. Conversion Basics Back to contents
--
2.1. Naming
The naming in converted header files should follow Borland's style as far as possible. This means, keep the original names, but make them more Delphi-like.
How should the C names be translated into Delphi?
The C-programmer usually uses upper case letters for type identifiers, e.g. MY_TYPE. In Delphi, a type identifier has a T-prefix followed by the name of the type in mixed (proper) case. Underscores are not used. The Delphi-like translation of the C type identifier MY_TYPE is TMyType.
In C older header files the pointer-type is named LPMY_TYPE. In translation to Delphi it should be PMyType to conform with Borland's style.
Constants are usually named identically to the original name, including upper case letters and underscores.
A few examples:
C
Delphi-Translation
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER,
*PIMAGE_FILE_HEADER;
type
PImageFileHeader = ^TImageFileHeader;
TImageFileHeader = packed record
Machine: Word;
NumberOfSections: Word;
TimeDateStamp: DWORD;
PointerToSymbolTable: DWORD;
NumberOfSymbols: DWORD;
SizeOfOptionalHeader: Word;
Characteristics: Word;
end;
#define LANG_NEUTRAL 0x00
#define LANG_AFRIKAANS 0x36
#define LANG_ALBANIAN 0x1C
#define LANG_ARABIC 0x01
#define LANG_BASQUE 0x2D
#define LANG_BELARUSIAN 0x23
#define LANG_BULGARIAN 0x02
#define LANG_CATALAN 0x03
#define LANG_CHINESE 0x04
CONST
LANG_NEUTRAL = $00;
LANG_AFRIKAANS = $36;
LANG_ALBANIAN = $1C;
LANG_ARABIC = $01;
LANG_BASQUE = $2D;
LANG_BELARUSIAN = $23;
LANG_BULGARIAN = $02;
LANG_CATALAN = $03;
LANG_CHINESE = $04;
2.2. Unit dependencies Back to contents --
C and C++ use #include to include header files in another header file or a source file. Delphi refers to units (in the USES clause) instead of header files.
For example
D3D.H includes D3DTYPES.H, D3DCAPS.H
D3DTYPES.H includes DDRAW.H
One unit contains one translation of a header file, so incorporation of D3DTYPES.H and D3DCAPS.H is required when translating D3D.H.
Thus the translation of D3D.H (D3D.PAS) needs D3DTYPES.PAS and D3DCAPS.PAS in uses.
In Windows.pas Borland has already done a lot of work for us. Borland's windows unit contains most of the basic Windows datatypes, so any translated unit needing Windows datatypes needs the Windows unit in its uses clause.
Note: In Delphi 1.0, substitute WinProcs.pas and WinTypes.pas for Windows.pas, since these two units include for Delphi 16-bit what Delphi 32-bit defines in Windows.pas. In Delphi 2 these two files are also aliased to Windows.pas in Delphi 32-bit versions for backward compatibility. Some header files contain source which is not directly translatable into Pascal, but the header file's impact on compilation must be incorporated into the translated code. For example, PSHPACK?.H contains compiler directives that are not directly translatable to Delphi; PSHPACK4.H directs the compiler to use 4-byte packing. More about this later.
2.3. #defines as constants
C and C++ use #defines in several ways. In a C header file #define can be used
for declaring a constant
for declaring a symbol for conditional compilation
for macros
This chapter describes the translation of #define into Delphi constants.
The format for declaring constants in C is:
#define NameOfConstant Value
For example:
#define TIME_ZONE_ID_UNKNOWN 0
#define TIME_ZONE_ID_STANDARD 1
#define TIME_ZONE_ID_DAYLIGHT 2
The translation in Delphi is:
CONST
TIME_ZONE_ID_UNKNOWN = 0;
TIME_ZONE_ID_STANDARD = 1;
TIME_ZONE_ID_DAYLIGHT = 2;
2.3.1. Hexadecimal values
C uses the prefix 0x to specify a hexadecimal value. For example, the C declaration
#define MY_CONSTANT 0xFF
translates to Delphi as
CONST
MY_CONSTANT = $FF;
3. Data Types
3.1. Basic Data Types
Here is a list of C data types and the equivalents in Delphi:
C
Delphi
UNSIGNED LONG
Dword (Longint)
UNSIGNED SHORT
word
INT
integer
UNSIGNED CHAR
byte, char (Depending on usage)
3.2. Windows API Common Types
The Windows API defines some common types for API usage. It is recommended that the same names be used in translations as far as possible. Windows.pas declares most of these types, some of which are listed below:
API Type declaration
Type used in Delphi Translation
Type Specification
ULONG
ULong
DWord
PULONG
PULong
^DWord
USHORT
UShort
SmallInt
PUSHORT
PUShort
^SmallInt
UCHAR
UChar
Byte
PUCHAR
PUChar
^Byte
DWORD
DWord
DWord
PDWORD, LPDWORD
PDWord
^DWord
BOOL
Bool
Bool
PBOOL, LPBOOL
PBool
^Bool
BYTE
Byte
Byte
PBYTE, LPBYTE
PByte
^Byte
WORD
Word
Word
PWORD, LPWORD
Pword
^Word
INT
Integer
Integer
PINT, LPINT
PInteger
^Integer
LPVOID
Pointer
Untyped Pointer
UINT
UInt
Integer
PUINT, LPUINT
PUInt
^Integer
WCHAR
WChar
WideChar
PWCHAR, LPWCHAR, PCWCH, LPCWCH, NWPSTR,
PWChar
^WideChar
PWSTR, LPWSTR
LPWStr
^WideChar
PCWSTR, LPCWSTR
LPCWStr
^WideChar
PCH, LPCH
PChar
^Char
PSTR, LPSTR
LPStr
^Char
PCSTR, LPCSTR
LPCStr
^Char
HANDLE
THandle
DWord
PHANDLE, LPHANDLE
PHandle
^DWord
3.3. Arrays - Two Methods
Method 1:
In C the first index of an array (or vector) is 0 and the declaration specifies the number of elements (not the last index), e.g.
DWORD MyType[4]
Delphi declares arrays as the range of elements, so the same declaration would be
MyType = Array [0..3] of DWord;
Method 2:
Alternatively, the number of elements may be specified by a constant, e.g
#define NumberOfElements 5
//...
typedef struct _MyRec {
DWORD MyArray[NumberOfElements]
} MyRec, *PMyRec
The same declaration in Delphi is
Const
NumberOfElements = 5
//...
Type
TmyArray = Record
MyArray : Array [0..NumberOfElements-1] of DWord;
end;
Remember, the range of the array is 0..NumberOfElements-1, but not0..NumberOfElements.