Tablice MIDL
Deklaratory tablic są wyświetlane w treści interfejsu pliku IDL jako jeden z następujących elementów:
- Część deklaracji ogólnej
- Element członkowski deklaratora struktury lub unii
- Parametr do zdalnego wywołania procedury
Granice każdego wymiaru tablicy są wyrażane wewnątrz oddzielnej pary nawiasów kwadratowych. Wyrażenie, które oblicza n oznacza dolną granicę zera i górną granicę n - 1. Jeśli nawiasy kwadratowe są puste lub zawierają pojedynczą gwiazdkę (*), dolna granica wynosi zero, a górna granica jest określana w czasie wykonywania.
Tablica może również zawierać dwie wartości oddzielone wielokropkami, które reprezentują dolne i górne granice tablicy, jak w sekcji [dolnej...górnej]. Microsoft RPC wymaga dolnej granicy zera. Kompilator MIDL nie rozpoznaje konstrukcji, które określają granice niezerowe.
Tablice mogą być skojarzone z atrybutami pól size_is, max_is, length_is, first_isi last_is w celu określenia rozmiaru tablicy lub części tablicy zawierającej prawidłowe dane. Te atrybuty pola identyfikują parametr, pole struktury lub stałą, która określa wymiar tablicy lub indeks.
Tablica musi być skojarzona z identyfikatorem określonym przez atrybut pola w następujący sposób: Gdy tablica jest parametrem, identyfikator musi być również parametrem tej samej funkcji; gdy tablica jest polem struktury, identyfikator musi być innym polem struktury tej samej struktury.
Tablica jest nazywana "zgodnym", jeśli górna granica dowolnego wymiaru jest określana w czasie wykonywania. (W czasie wykonywania można określić tylko górne granice). Aby określić górną granicę, deklaracja tablicy musi zawierać atrybut size_is lub max_is.
Tablica jest nazywana "różną", gdy jej granice są określane w czasie kompilacji, ale zakres przesyłanych elementów jest określany w czasie wykonywania. Aby określić zakres przesyłanych elementów, deklaracja tablicy musi zawierać atrybut length_is, first_islub last_is.
Zgodna tablica różna (nazywana również "otwartą") to tablica, której górna granica i zakres przesyłanych elementów są określane w czasie wykonywania. Co najwyżej jedna zgodna lub zgodna tablica może być zagnieżdżona w strukturze języka C i musi być ostatnim elementem struktury. Z kolei niekonformantne różne tablice mogą występować w dowolnym miejscu w strukturze.
Przykłady
/* 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..*]
);
Aby uzyskać więcej informacji, zobacz Arrays and Pointers.
Tablice wielowymiarowe
Użytkownik może zadeklarować typy, które są tablicami, a następnie zadeklarować tablice obiektów takich typów. Semantyka m-wymiarowych tablic n-wymiarowych typów tablic są takie same jak semantyka m+n-tablic wymiarowych.
Na przykład typ RECT_TYPE można zdefiniować jako tablicę dwuwymiarową, a zmienna można zdefiniować jako tablicę RECT_TYPE. Jest to odpowiednik trójwymiarowej tablicy 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 jest zorientowany na C. Zgodnie z konwencjami języka C w czasie wykonywania można określić tylko pierwszy wymiar tablicy wielowymiarowej. Współdziałanie z macierzami IDL DCE obsługującymi inne języki jest ograniczone do:
- Tablice wielowymiarowe ze stałymi (określanymi w czasie kompilacji) granicami.
- Tablice wielowymiarowe ze wszystkimi granicami stałymi z wyjątkiem pierwszego wymiaru. Górna granica i zakres przesłanych elementów pierwszego wymiaru zależą od środowiska uruchomieniowego.
- Wszystkie tablice jednowymiarowe z dolną granicą zerem.
Gdy atrybut [ciąg] jest używany w tablicach wielowymiarowych, atrybut ma zastosowanie do najbardziej prawej tablicy.
Tablice wskaźników
Wskaźniki referencyjne muszą wskazywać prawidłowe dane. Aplikacja kliencka musi przydzielić całą pamięć dla [w] lub [in,] tablicy wskaźników referencyjnych, zwłaszcza gdy tablica jest skojarzona z [in]lub [in,out], [length_is], lub [last_is] wartości. Aplikacja kliencka musi również zainicjować wszystkie elementy tablicy przed wywołaniem. Przed powrotem do klienta aplikacja serwera musi sprawdzić, czy wszystkie elementy tablicy w przesłanym punkcie zakresu do prawidłowego magazynu.
Po stronie serwera wycinkowy przydziela magazyn dla wszystkich elementów tablicy, niezależnie od [length_is] lub [last_is] wartości w momencie wywołania. Ta funkcja może mieć wpływ na wydajność aplikacji.
Żadne ograniczenia nie są nakładane na tablice unikatowych wskaźników. Na kliencie i serwerze magazyn jest przydzielany dla wskaźników o wartości null. Gdy wskaźniki nie mają wartości null, dane są umieszczane w magazynie wstępnie alokowanym.
Opcjonalny deklarator wskaźnika może poprzedzać deklarator tablicy.
Jeśli osadzone wskaźniki odniesienia są [się]-only parameters, kod menedżera serwera musi przypisać prawidłowe wartości do tablicy wskaźników referencyjnych. Na przykład:
typedef [ref] short * ARefPointer;
typedef ARefPointer ArrayOfRef[10];
HRESULT proc1( [out] ArrayOfRef Parameter );
Wygenerowane wycinki przydzielają tablicę i przypisują wartości null do wszystkich wskaźników osadzonych w tablicy.