MIDL-Arrays
Array-Deklaratoren werden im Schnittstellentext der IDL-Datei wie folgt angezeigt:
- Teil einer allgemeinen Deklaration
- Ein Mitglied eines Deklarators vom Typ „structure“ oder „union“
- Ein Parameter für einen Remoteprozeduraufruf
Die Grenzen jeder Dimension des Arrays werden in einem separaten Paar eckiger Klammern ausgedrückt. Ein Ausdruck der als n ausgedrückt wird, bedeutet eine Untergrenze von Null und eine Obergrenze von n - 1. Wenn die eckigen Klammern leer sind oder ein einzelnes Sternchen (*) enthalten, ist die Untergrenze Null und die Obergrenze wird zur Laufzeit bestimmt.
Das Array kann auch zwei Werte enthalten, die durch Auslassungspunkte getrennt sind, die die Unter- und Obergrenzen des Arrays darstellen, wie in [lower...upper]. Microsoft RPC erfordert eine Untergrenze von Null. Der MIDL-Compiler erkennt keine Konstrukte, die Untergrenzen ungleich Null angeben.
Arrays können den Feldattributen size_is, max_is, length_is, first_is und last_is zugeordnet sein, um die Größe des Arrays oder des Teils des Arrays anzugeben, der gültige Daten enthält. Diese Feldattribute identifizieren den Parameter, das Strukturfeld oder die Konstante, die die Arraydimension oder den Index angibt.
Das Array muss mit der durch das Feldattribut angegebenen Kennung folgendermaßen verknüpft sein: Wenn das Array ein Parameter ist, muss die Kennung auch ein Parameter derselben Funktion sein. Wenn das Array ein Strukturfeld ist, muss die Kennung ein anderes Strukturfeld derselben Struktur sein.
Ein Array wird als „konform“ bezeichnet, wenn die Obergrenze einer beliebigen Dimension zur Laufzeit bestimmt wird. (Zur Laufzeit können nur Obergrenzen bestimmt werden.) Um die Obergrenze zu bestimmen, muss die Arraydeklaration ein size_is- oder max_is-Attribut enthalten.
Ein Array wird als „variierend“ bezeichnet, wenn seine Grenzen zur Kompilierungszeit festgelegt werden, der Bereich der übertragenen Elemente jedoch zur Laufzeit bestimmt wird. Um den Bereich der übertragenen Elemente zu bestimmen, muss die Arraydeklaration ein length_is-, first_is- oder last_is-Attribut enthalten.
Ein konformes variierendes Array (auch „offen“ genannt) ist ein Array, dessen Obergrenze und Bereich der übertragenen Elemente zur Laufzeit bestimmt werden. In einer C-Struktur kann höchstens ein konformes oder konform variierendes Array verschachtelt werden und muss das letzte Element der Struktur sein. Im Gegensatz dazu können nicht konforme, variierende Arrays überall in einer Struktur auftreten.
Beispiele
/* IDL file interface body */
#define MAX_INDEX 10
typedef char ATYPE[MAX_INDEX];
typedef short BTYPE[]; // Equivalent to [*];
typedef long CTYPE[*][10]; // [][10]
typedef float DTYPE[0..10]; // Equivalent to [11]
typedef float ETYPE[0..(MAX_INDEX)];
typedef struct
{
unsigned short size;
unsigned short length;
[size_is(size), length_is(length)] char string[*];
} counted_string;
HRESULT MyFunction(
[in, out] short * pSize,
[in, out, string, size_is(*pSize)] char a[0..*]
);
Weitere Informationen finden Sie unter Arrays und Zeiger.
Mehrdimensionale Arrays
Der Benutzer kann Typen deklarieren, die Arrays sind, und dann Arrays von Objekten solcher Typen deklarieren. Die Semantik von m-dimensional-Arrays von n-dimensional-Arraytpen entsprechen der Semantik von m+n-dimensional-Arrays.
Beispielsweise kann der Typ RECT_TYPE als zweidimensionales Array definiert werden, und die Variable rect kann als Array von RECT_TYPE definiert werden. Dies entspricht dem dreidimensionalen Array equivalent_rect:
typedef short int RECT_TYPE[10][20];
RECT_TYPE rect[15];
short int equivalent_rect[15][10][20]; // ~RECT_TYPE rect[15]
Microsoft RPC ist auf C ausgerichtet. Gemäß den Konventionen der C-Sprache kann zur Laufzeit nur die erste Dimension eines mehrdimensionalen Arrays bestimmt werden. Die Interoperabilität mit DCE IDL-Arrays, die andere Sprachen unterstützen, ist auf Folgendes beschränkt:
- Mehrdimensionale Arrays mit konstanten (durch die Kompilierungszeit festgelegten) Grenzen.
- Mehrdimensionale Arrays mit ausschließlich konstanten Grenzen außer der ersten Dimension. Die Obergrenze und der Bereich der übertragenen Elemente der ersten Dimension sind laufzeitabhängig.
- Alle eindimensionalen Arrays mit einer Untergrenze von Null.
Wenn das [string]-Attribut in mehrdimensionalen Arrays verwendet wird, gilt das Attribut für das ganz rechte Array.
Arrays von Zeigern
Referenzzeiger müssen auf gültige Daten verweisen. Die Clientanwendung muss den gesamten Arbeitsspeicher für ein [in] oder [ in,out] Array an Referenzzeigern zuweisen, insbesondere wenn das Array mit den Werten [in] oder [ in,out], [length_is] oder [last_is] verbunden ist. Außerdem muss die Clientanwendung vor dem Aufruf alle Array-Elemente initialisieren. Vor der Rückkehr zum Client muss die Serveranwendung überprüfen, ob alle Array-Elemente im übertragenen Bereich auf einen gültigen Speicher verweisen.
Auf der Serverseite reserviert der Stub Speicher für alle Array-Elemente, unabhängig von dem Wert [length_is] oder [last_is] zum Zeitpunkt des Aufrufs. Diese Funktion kann die Leistung Ihrer Anwendung beeinträchtigen.
Es gelten keine Einschränkungen für Arrays eindeutiger Zeiger. Sowohl auf dem Client als auch auf dem Server wird Speicher für Nullzeiger reserviert. Wenn Zeiger ungleich Null sind, werden die Daten im vorab zugewiesenen Speicher abgelegt.
Ein optionaler Zeiger-Deklarator kann dem Array-Deklarator vorausgehen.
Wenn eingebettete Referenzzeiger [out] reine Parameter sind, muss der Server-Manager-Code dem Array von Referenzzeigern gültige Werte zuweisen. Zum Beispiel:
typedef [ref] short * ARefPointer;
typedef ARefPointer ArrayOfRef[10];
HRESULT proc1( [out] ArrayOfRef Parameter );
Die generierten Stubs weisen das Array zu und weisen allen im Array eingebetteten Zeigern Nullwerte zu.