Matrizes MIDL
Os declaradores de matriz aparecem no corpo da interface do arquivo IDL como um dos seguintes:
- Parte de uma declaração geral
- Um membro de uma estrutura ou um declarador de união
- Um parâmetro para uma chamada de procedimento remoto
Os limites de cada dimensão da matriz são expressos dentro de um par separado de colchetes. Uma expressão que é avaliada como n indica um limite mínimo de zero e um limite máximo de n - 1. Se os colchetes estiverem vazios ou contiverem um único asterisco (*), o limite mínimo será zero e o limite máximo será determinado em tempo de execução.
A matriz também pode conter dois valores separados por reticências que representam os limites mínimo e máximo da matriz, como em [lower...upper]. O Microsoft RPC requer um limite mínimo de zero. O compilador MIDL não reconhece construções que especificam limites mínimos diferentes de zero.
As matrizes podem ser associadas aos atributos de campo size_is, max_is, length_is, first_is e last_is para especificar o tamanho da matriz ou a parte da matriz que contém dados válidos. Esses atributos de campo identificam o parâmetro, o campo de estrutura ou a constante que especifica a dimensão ou o índice da matriz.
A matriz deve ser associada ao identificador especificado pelo atributo de campo da seguinte maneira: quando a matriz é um parâmetro, o identificador também deve ser um parâmetro para a mesma função. Quando a matriz é um campo de estrutura, o identificador deve ser outro campo dessa mesma estrutura.
Uma matriz será chamada de "conformante" se o limite máximo de qualquer dimensão for determinado em tempo de execução. (Somente os limites máximos podem ser determinados em tempo de execução.) Para determinar o limite máximo, a declaração de matriz deve incluir um atributo size_is ou max_is.
Uma matriz é chamada de "variável" quando os limites são determinados em tempo de compilação, mas o intervalo de elementos transmitidos é determinado em tempo de execução. Para determinar o intervalo de elementos transmitidos, a declaração de matriz deve incluir um atributo length_is, first_is ou last_is.
Uma matriz variável em conformidade (também chamada de "aberta") é uma matriz cujo limite máximo e o intervalo de elementos transmitidos são determinados em tempo de execução. No máximo, uma matriz variável em conformidade ou em conformidade pode ser aninhada em uma estrutura C e deve ser o último elemento da estrutura. Em contraste, matrizes variáveis incompatíveis podem ocorrer em qualquer lugar em uma estrutura.
Exemplos
/* 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..*]
);
Para obter mais informações, consulte Matrizes e ponteiros.
Matrizes multidimensionais
O usuário pode declarar tipos que são matrizes e, em seguida, declarar matrizes de objetos desses tipos. A semântica de matrizes de dimensão m de tipos de dimensão n é a mesma que a semântica de matrizes de dimensão m+n.
Por exemplo, o tipo RECT_TYPE pode ser definido como uma matriz bidimensional e a variável rect pode ser definida como uma matriz de RECT_TYPE. Isso é equivalente à matriz tridimensional equivalent_rect:
typedef short int RECT_TYPE[10][20];
RECT_TYPE rect[15];
short int equivalent_rect[15][10][20]; // ~RECT_TYPE rect[15]
O Microsoft RPC tem orientação C. Seguindo as convenções da linguagem C, apenas a primeira dimensão de uma matriz multidimensional pode ser determinada em tempo de execução. A interoperação com matrizes DCE IDL que dão suporte a outras linguagens é limitada a:
- Matrizes multidimensionais com limites constantes (determinados pelo tempo de compilação).
- Matrizes multidimensionais com todos os limites constantes, exceto a primeira dimensão. O limite máximo e o intervalo de elementos transmitidos da primeira dimensão dependem do tempo de execução.
- Quaisquer matrizes unidimensionais com um limite mínimo de zero.
Quando o atributo [string] é usado em matrizes multidimensionais, o atributo se aplica à matriz mais à direita.
Matrizes de ponteiros
Os ponteiros de referência devem apontar para dados válidos. O aplicativo cliente deve alocar toda a memória para uma matriz [in] ou [ in,out] de ponteiros de referência, especialmente quando a matriz está associada a valores [in] ou [ in,out], [length_is], or [last_is]. O aplicativo cliente também deve inicializar todos os elementos da matriz antes da chamada. Antes de retornar ao cliente, o aplicativo de servidor deve verificar se todos os elementos de matriz no intervalo transmitido apontam para um armazenamento válido.
No lado do servidor, o stub aloca armazenamento para todos os elementos da matriz, independentemente do valor [length_is] ou [last_is] no momento da chamada. Esse recurso pode afetar o desempenho do seu aplicativo.
Nenhuma restrição é colocada em matrizes de ponteiros exclusivos. No cliente e no servidor, o armazenamento é alocado para ponteiros nulos. Quando os ponteiros não são nulos, os dados são colocados no armazenamento pré-alocado.
Um declarador de ponteiro opcional pode preceder o declarador de matriz.
Quando os ponteiros de referência inseridos são parâmetros somente [out], o código do gerenciador do servidor deve atribuir valores válidos à matriz de ponteiros de referência. Por exemplo:
typedef [ref] short * ARefPointer;
typedef ARefPointer ArrayOfRef[10];
HRESULT proc1( [out] ArrayOfRef Parameter );
Os stubs gerados alocam a matriz e atribuem valores nulos a todos os ponteiros inseridos na matriz.