Layout do ponteiro
O layout de ponteiro descreve ponteiros de uma estrutura ou matriz.
pointer_layout<>
Um campo pointer_layout<> consiste nos caracteres de formato FC_PP FC_PAD seguidos por uma ou mais descrições de ponteiro, conforme descrito posteriormente, e terminando com um caractere de formato FC_END:
FC_PP
FC_PAD
{ pointer_instance_layout<> }*
FC_END
Um campo pointer_instance_layout<> é uma cadeia de caracteres de formato que descreve instâncias únicas ou múltiplas de ponteiros. Os seguintes campos são usados nesses descritores:
offset_in_memory
O deslocamento assinado para o local do ponteiro na memória. Para um ponteiro que reside em uma estrutura, esse deslocamento é um deslocamento negativo do final da estrutura (o final da porção não conforme das estruturas conformes); para matrizes, o deslocamento é do início da matriz.
offset_in_buffer
O deslocamento assinado para o local do ponteiro no buffer. Para um ponteiro que reside em uma estrutura, esse deslocamento é um deslocamento negativo do final da estrutura (o final da parte não conforme das estruturas conformantes): para matrizes, o deslocamento é do início da matriz.
offset_to_array
Deslocamento de uma estrutura de fechamento para a matriz incorporada cujos ponteiros estão sendo manipulados. Para matrizes de nível superior, esse campo sempre será zero.
do treinamento
Número total de ponteiros que têm o mesmo layout<> descrito.
increment
Incremento entre ponteiros sucessivos durante uma REPEAT.
number_of_pointers
Número de ponteiros diferentes em uma instância de repetição.
pointer_description
Descrição do ponteiro.
Todos os layouts de instância de ponteiro usam o seguinte pointer_instance<8> único:
offset_to_pointer_in_memory<2>
offset_to_pointer_in_buffer<2>
pointer_description<4>
A seguir estão os descritores de instância:
Instância única de um ponteiro para um tipo simples:
FC_NO_REPEAT FC_PAD
pointer_instance<8>
Ponteiro de repetição fixo:
FC_FIXED_REPEAT FC_PAD
iterations<2>
increment<2>
offset_to_array<2>
number_of_pointers<2>
{ pointer_instance<8> }*
Ponteiro de repetição variável:
FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET)
increment<2>
offset_to_array<2>
number_of_pointers<2>
{ pointer_instance<8> }*
Para instâncias de ponteiro de repetição fixa e repetição variável, há um conjunto de descrições de deslocamento e ponteiro para cada ponteiro na instância de repetição.
Problemas de design de layout de ponteiros
Esta seção aborda problemas relacionados ao processamento de estruturas conformes e ponteiros incorporados. O problema é que o compilador gera layouts de ponteiro para estruturas e matrizes com alguma redundância. Isso é benéfico, porque as informações são úteis e, como tal, por exemplo, uma estrutura em conformidade pode percorrer um layout de ponteiro para atender a todos os ponteiros da estrutura e da matriz conforme que faz parte da estrutura conformante. No entanto, existem algumas situações incorporadas que exigem que o mecanismo de notificação de falha na entrega execute trabalho adicional para processar todos os layouts de ponteiro na sequência adequada, processando cada ponteiro exatamente uma vez.
O que o compilador gera
Cada objeto discutido nesta seção tem ponteiros, portanto, por exemplo, uma estrutura em conformidade tem ponteiros na parte da estrutura, bem como nos elementos da matriz. O elemento é uma estrutura simples com um ponteiro.
Estrutura conforme, nível único
O descritor em conformidade tem uma parte PP onde todos os ponteiros são descritos, tanto da estrutura quanto da matriz. A lista de membros tem FC_LONG no lugar de um ponteiro. O descritor de matriz CARRAY tem elementos por meio do uso de um embedded_complex e nenhum descritor de ponteiro. O elemento ainda tem seu descritor de ponteiro único. O layout de ponteiro precede o layout de membro em uma estrutura em conformidade e descritores de estrutura simples.
Estrutura conforme, dois ou mais níveis
A descrição do PP tem ponteiros de todos os níveis. Ele reutiliza a mesma descrição de matriz que a estrutura interna conformante. A lista de membros tem FC_LONG no lugar de um ponteiro. Uma estrutura embutida vem através do uso de um complexo embutido. O descritor de estrutura conforme é reutilizado no estado em que se encontra. O tamanho da parte plana da estrutura também sai completo, o que significa que o tamanho da estrutura de nível superior incluiria o tamanho plano da estrutura embutida.
Estrutura complexa, nível único
Os membros do ponteiro são marcados por FC_POINTER. O layout do ponteiro é simplificado de forma que haja um descritor de ponteiro (4 bytes) para cada entrada FC_POINTER na lista. O layout do ponteiro é percorrido em paralelo com uma caminhada de membro, ou seja, uma FC_POINTER faz com que a próxima descrição do ponteiro seja processada. A matriz CARRAY tem layout de ponteiro com todos os descritores da matriz e, em seguida, elemento, através do uso de um complexo incorporado. O descritor do elemento é reutilizado. O tamanho da porção plana da estrutura sai completo; Em outras palavras, o tamanho plano da estrutura de nível superior inclui o tamanho plano da estrutura incorporada. O layout de membro precede o layout de ponteiro para estruturas complexas.
Assim, a geração da descrição da matriz conformante é diferente dependendo se é uma matriz dentro de uma estrutura conformante ou dentro de uma estrutura complexa.
Estrutura complexa, 2 ou mais níveis, complexa em complexo
A estrutura complexa de nível superior tem seus ponteiros membros, a estrutura complexa incorporada tem seus ponteiros membros. O descritor de estrutura conforme é reutilizado. O descritor de matriz da parte superior é a matriz reutilizada da estrutura incorporada.
Estrutura complexa com uma estrutura em conformidade incorporada
A estrutura em conformidade Top=level tem seus ponteiros de membro. O descritor de estrutura conforme é reutilizado no estado em que se encontra. O descritor de matriz é reutilizado a partir da estrutura em conformidade incorporada; em outras palavras, ele não tem nenhum ponteiro no descritor de matriz. O elemento tem seu descritor de ponteiro.
Matrizes de estruturas com ponteiros
Uma matriz de estruturas simples com ponteiros é gerada como SMFARRAY ou CARRAY, dependendo se a matriz é dimensionada, mas em ambos os casos ela tem um layout de ponteiro completo (FIXED_REPEAT ou VARIABLE_REPEAT). O layout de ponteiro vem antes do layout de membro.
Uma matriz de estruturas complexas com ponteiros é gerada como BOGUS_ARRAY independentemente de ser fixa ou dimensionada e, em ambos os casos, não tem nenhum layout de ponteiro.
O que o mecanismo de notificação de falha na entrega faz
Esta seção descreve o comportamento do mecanismo de notificação de falha na entrega.
O passe marshaling
Estruturas conformantes e estrutura conformante embutida.
A estrutura de nível superior se comporta como uma estrutura de nível único.
Estrutura complexa embutida com matriz em conformidade
Qualquer estrutura complexa força a estrutura externa a ser uma estrutura complexa. A estrutura embutida nunca marca sua matriz. Toda estrutura sempre passa por ponteiros embutidos, simplesmente reunindo membros e um membro sendo um FC_POINTER.
Estrutura complexa com estrutura em conformidade
A estrutura em conformidade mais embutida mais alta comanda a matriz em conformidade e todas as pontas. O mecanismo NDR nunca desce para estruturas conformes aninhadas mais profundas, se houver; Isso simplifica a solução, pois uma estrutura em conformidade é um objeto de folha no que diz respeito ao empacotamento de objetos incorporados. A estrutura complexa de nível superior ignora o empacotamento de matriz.
Desmarshaling, bufsizing e passes livres
O desmarshaling é simétrico ao marshaling; a primeira operação que ele executa para estruturas complexas é descobrir a localização dos ponteiros no buffer por meio da chamada da função NdrComplexStructBufferSize . Em seguida, desmarshals pointees em paralelo, permitindo que o mesmo esquema para desmarshaling os pointees corretamente seja usado. Não deve haver confusão sobre objetos de tamanho e uniões; A imagem de memória não deve ser usada para objetos de tamanho e uniões, apenas para o conteúdo do buffer.
As bandeiras usadas para realizar o marshaling e o unmarshaling corretamente são usadas da mesma forma no bufsizing e na liberação para garantir que as pontas sejam pisadas exatamente uma vez.
Passe de endianness
No início, o passo de endianidade é um pouco semelhante ao marshaling/unmarshaling; Duas passagens são necessárias para processar estruturas complexas. A primeira passagem converte a parte plana e encontra a localização dos ponteiros no buffer semelhante a como o bufsizing executa essa operação para desmarshaling. O segundo passe, então, converte os ponteiros.
Os passes de endianness diferem da seguinte maneira: cada estrutura e cada membro tem que ser escalonado até que o membro ou elemento da folha seja um tipo simples. Isso é diferente de unmarshaling; No desmarshaling, por exemplo, nunca há necessidade de processar estruturas conformantes embutidas em estruturas conformes, ou qualquer membro da estrutura conformante. Outra questão é que a conversão não é uma operação idempotente – portanto, o passe de desmarshaling poderia refazer o desempacotamento de algumas peças sem danos, enquanto a conversão tem que ser realizada estritamente uma vez por qualquer tipo simples.
Assim, o algoritmo de endianidade pode ser resumido da seguinte forma. A NDR tem uma noção da estrutura de conformidade de nível superior e um sinalizador para marcar isso, conforme apropriado. Ao caminhar pela primeira vez, como para converter a porção plana e obter a localização das pontas, essa noção não seria usada. O NDR desceria pelas partes planas de todos os níveis de estruturas e nunca se aventuraria no processamento de ponteiros. Finalmente, a notificação de falha na entrega converteria o array no nível superior.
Ao caminhar pela segunda vez, a bandeira seria usada para marcar a passagem do ponteiro embutido para evitar entrar em níveis mais profundos das estruturas conformantes, em seguida, a estrutura mais conforme. Dessa forma, a bandeira forçaria o comportamento comum de marshaling/unmarshaling, que é evitar descer para níveis mais profundos de estruturas conformantes.
A segunda passagem para estruturas complexas com matrizes conformantes funciona da seguinte forma: as estruturas complexas funcionam da maneira comum; o que significa que os níveis mais profundos nunca olhariam ou ignorariam seu tamanho conforme ou seus arrays conformantes, e prefeririam simplesmente andar seus membros sem tocar no array.
Para estruturas complexas com estruturas conformes, a estrutura conformante deve estar ciente se é de nível superior e se está em uma estrutura complexa. A parte plana do array é processada pela estrutura mais condizente. Na segunda passagem, a estrutura mais conformada pularia a parte plana e passaria pelo layout do ponteiro e retornaria. A estrutura mais complexa pularia sua parte plana e também pularia o layout do ponteiro.
O aspecto robusto da endianidade caminha
A caminhada de endianness verifica as condições usuais fora do buffer e realiza outras verificações de natureza não correlacionada. As verificações destinadas a valores correlacionados (como o argumento de dimensionamento versus o tamanho conforme) não podem ser realizadas usando esta etapa; elas são realizadas mais tarde, quando o desmarshaling.