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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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

  1. Estruturas conformantes e estrutura conformante embutida.

    A estrutura de nível superior se comporta como uma estrutura de nível único.

  2. 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.

  3. 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.