PreviousNext

IDL to C Type Mappings

Many of the primitive C data types represent items of different sizes on different machines. For example, an int may be 16 bits on one machine and 32 bits on another. These ambiguities can cause portability problems for some C programs, and they are intolerable for RPC programs. A parameter to an RPC call must represent the same size data item on both the client and server machine, whatever the machine architectures.

This means that when IDL declarations are compiled to generate C language headers and stubs, a given IDL type must always be declared in the corresponding C code as a C type of a specific length, no matter what machine the IDL compilation is done on.

To achieve this, the following must be true:

1. Each IDL primitive type is always represented in the generated C files, by a specific defined C type

2. Each of the specific defined C types is defined by the local implementation of DCE so that it represents a data type of the correct length.

For example, a parameter declared in the IDL as a short, will be declared in the IDL generated header file as the defined type idl_short_int. Each implementation of DCE then defines the idl_shor_int type correctly for the local C compiler and machine architecture to be an integer 16 bits long. For example, on a 32-bit machine, the idl_short_int type is typically defined as a short int.

When you write application code that refers to a parameter declared in the IDL, you must use a type that declares a data item of the same length. The safest policy is to use the same specific defined C type used in the headers and stubs. For example, your IDL file might declare the following:

void my_op([in,out] short var);

In this case, your server manager code would contain an function that looks something like this:

void my_op(idl_short_int var)
{
.
.
.
}

On a 32-bit machine, your code could probably use a short safely (since that is how your implementation probably defines idl_short_int, but such usage is not portable to other machine types and is therefore not recommended.

The following tables show the IDL to C type mappings for the IDL primitive types.


IDL/NDR/C Type Mappings: Part 1

IDL Type NDR Type Defined C Type C Type
boolean boolean idl_boolean unsigned char
char character idl_char unsigned char
byte uninterpreted octet idl_byte unsigned char
small small idl_small_int char
short short idl_short_int short int
long long idl_long_int long int
hyper hyper idl_hyper_int 16- or 32- Bit Machines: Big Endian:
struct {
long high;
unsigned long low;
}

Little Endian:
struct {
unsigned long low;
long high;
}

64-Bit Machines:
long
unsigned small unsigned small idl_usmall_int unsigned char
unsigned short unsigned short idl_ushort_int unsigned short int
unsigned long unsigned long idl_ulong_int unsigned long int
unsigned hyper unsigned hyper idl_uhyper_int 16- or 32-Bit Machines:
Big Endian:
struct {
unsigned long high;
unsigned long low;
}

Little Endian:
struct {
unsigned long low;
unsigned long high;
}

64-Bit Machines: unsigned long

IDL/NDR/C Type Mappings: Part 2

IDL Type NDR Type Defined C Type C Type
float float idl_float float
double double idl_double double
handle_t not transmitted handle_t void *
error_status_t unsigned long idl_ulong_int unsigned long int
ISO_LATIN_1 uninterpreted octet ISO_LATIN_1 byte
ISO_MULTI_LINGUAL (Note 1.) ISO_MULTI_LINGUAL struct{
byte row;
byte column;
}
ISO_UCS (Note 1.) ISO_UCS struct{
byte group;
byte plane;
byte row;
byte column;
}
In addition to the IDL primitive type mappings defined in the table, implementations provide a set of convenient typedefs that map the listed defined types into types that explicitly name amounts of storage. These are defined in IDL as follows:

typedef unsigned small unsigned8; /* positive 8-bit integer */
typedef unsigned short unsigned16; /* positive 16-bit integer */
typedef unsigned long unsigned32; /* positive 32-bit integer */
typedef small signed8; /* signed 8-bit integer */
typedef short signed16; /* signed 16-bit integer */
typedef long signed32; /* signed 32-bit integer */
typedef unsigned32 boolean32; /* a 32-bit boolean */

They are defined in C as follows:

typedef idl_usmall_int unsigned8;
typedef idl_ushort_int unsigned16;
typedef idl_ulong_int unsigned32;
typedef idl_small_int signed8;
typedef idl_short_int signed16;
typedef idl_long_int signed32;
typedef unsigned32 boolean32;

As a matter of programming style, these types have the advantage that the size of the declared data items is explicitly stated. For this reason their use in both IDL declarations and application C code is recommended. Note also that the following IDL and C typedefs are also made available by implementations a convenient portable declaration for status parameters:

typedef unsigned long error_status_t;

typedef idl_ulong_int error_status_t;