Layout puntatore
Il layout del puntatore descrive i puntatori di una struttura o di una matrice.
pointer_layout<>
Un campo pointer_layout<> è costituito dai caratteri di formato FC_PP FC_PAD seguiti da una o più descrizioni del puntatore, come descritto più avanti e terminando con un carattere di formato FC_END:
FC_PP
FC_PAD
{ pointer_instance_layout<> }*
FC_END
Un campo pointer_instance_layout<> è una stringa di formato che descrive singole o più istanze di puntatori. I campi seguenti vengono usati in questi descrittori:
offset_in_memory
Offset con segno nella posizione del puntatore in memoria. Per un puntatore che risiede in una struttura, questo offset è un offset negativo dalla fine della struttura (la fine della parte non conforme delle strutture conformi); per le matrici, l'offset è dall'inizio della matrice.
offset_in_buffer
Offset con segno nella posizione del puntatore nel buffer. Per un puntatore che si trova in una struttura, questo offset è un offset negativo dalla fine della struttura (la fine della parte non conforme delle strutture conformi): per le matrici, l'offset è dall'inizio della matrice.
offset_to_array
Offset da una struttura di inclusione alla matrice incorporata i cui puntatori vengono gestiti. Per le matrici di livello superiore, questo campo sarà sempre zero.
iterations
Numero totale di puntatori con lo stesso layout<> descritto.
increment
Incrementare tra puntatori successivi durante un REPEAT.
number_of_pointers
Numero di puntatori diversi in un'istanza di ripetizione.
pointer_description
Descrizione del puntatore.
Tutti i layout dell'istanza del puntatore usano il seguente pointer_instance<8>:
offset_to_pointer_in_memory<2>
offset_to_pointer_in_buffer<2>
pointer_description<4>
Di seguito sono riportati i descrittori di istanza:
Singola istanza di un puntatore a un tipo semplice:
FC_NO_REPEAT FC_PAD
pointer_instance<8>
Puntatore a ripetizione fisso:
FC_FIXED_REPEAT FC_PAD
iterations<2>
increment<2>
offset_to_array<2>
number_of_pointers<2>
{ pointer_instance<8> }*
Puntatore a ripetizione variabile:
FC_VARIABLE_REPEAT (FC_FIXED_OFFSET | FC_VARIABLE_OFFSET)
increment<2>
offset_to_array<2>
number_of_pointers<2>
{ pointer_instance<8> }*
Per le istanze del puntatore a ripetizione fissa e di ripetizione delle variabili è presente un set di descrizioni di offset e puntatore per ogni puntatore nell'istanza di ripetizione.
Problemi di progettazione del layout dei puntatori
Questa sezione risolve i problemi relativi all'elaborazione di strutture conformi e puntatori incorporati. Il problema è che il compilatore genera layout del puntatore per strutture e matrici con una certa ridondanza. Ciò è utile perché le informazioni sono utili e, ad esempio, una struttura conforme può camminare un layout di puntatore per gestire tutti i puntatori dalla struttura e dalla matrice conforme che fa parte della struttura conforme. Esistono tuttavia alcune situazioni incorporate che richiedono al motore NDR di eseguire operazioni aggiuntive per elaborare tutti i layout del puntatore nella sequenza corretta, elaborando ogni puntatore esattamente una volta.
Cosa genera il compilatore
Ogni oggetto descritto in questa sezione include puntatori, pertanto ad esempio una struttura conforme include puntatori nella parte della struttura e negli elementi della matrice. L'elemento è una struttura semplice con un puntatore.
Struttura conforme, livello singolo
Il descrittore conforme ha una parte PP in cui sono descritti tutti i puntatori, sia dalla struttura che dalla matrice. L'elenco dei membri ha FC_LONG anziché un puntatore. Il descrittore di matrice JSONY dispone di elementi tramite l'uso di un embedded_complex e nessun descrittore puntatore. L'elemento ha ancora il relativo descrittore puntatore singolo. Il layout del puntatore precede il layout del membro in una struttura conforme e descrittori di struttura semplici.
Struttura conforme, due o più livelli
La descrizione PP include puntatori di tutti i livelli. Riutilizza la stessa descrizione della matrice della struttura conforme interna. L'elenco dei membri ha FC_LONG anziché un puntatore. Una struttura incorporata viene usata da un complesso incorporato. Il descrittore di struttura conforme viene riutilizzato così come è. Anche le dimensioni della parte piatta della struttura vengono completate, vale a dire che le dimensioni della struttura di primo livello includono le dimensioni flat della struttura incorporata.
Struttura complessa, livello singolo
I membri del puntatore sono contrassegnati da FC_POINTER. Il layout del puntatore è semplificato in modo che sia presente un descrittore puntatore (4 byte) per ogni voce FC_POINTER nell'elenco. Il layout del puntatore viene camminato in parallelo con una passeggiata membro, ovvero un FC_POINTER fa sì che la descrizione del puntatore successiva venga elaborata. La matrice DELL'OPZIONE HA un layout puntatore con tutti i descrittori della matrice e quindi l'elemento, tramite l'uso di un complesso incorporato. Il descrittore di elemento viene riutilizzato. La dimensione della parte piatta della struttura viene completata; in altre parole, le dimensioni flat della struttura di primo livello includono le dimensioni flat della struttura incorporata. Il layout del membro precede il layout del puntatore per strutture complesse.
Di conseguenza, la generazione della descrizione della matrice conforme è diversa a seconda che si tratti di una matrice all'interno di una struttura conforme o all'interno di una struttura complessa.
Struttura complessa, 2 o più livelli, complessi in complessi
La struttura complessa di primo livello ha i puntatori ai membri, la struttura complessa incorporata ha i puntatori ai membri. Il descrittore di struttura conforme viene riutilizzato. Il descrittore di matrice dalla parte superiore è la matrice riutilizzata dalla struttura incorporata.
Struttura complessa con una struttura conforme incorporata
La struttura conforme al livello superiore ha i puntatori ai membri. Il descrittore di struttura conforme viene riutilizzato così come è. Il descrittore di matrice viene riutilizzato dalla struttura conforme incorporata; in altre parole, non dispone di puntatori nel descrittore di matrice. L'elemento ha il descrittore del puntatore.
Matrici di strutture con puntatori
Una matrice di strutture semplici con puntatori viene generata come SMFARRAY o JSONY a seconda che la matrice sia ridimensionata, ma in entrambi i casi ha un layout del puntatore completo (FIXED_REPEAT o VARIABLE_REPEAT). Il layout del puntatore precede il layout del membro.
Una matrice di strutture complesse con puntatori viene generata come BOGUS_ARRAY indipendentemente dal fatto che sia fissa o ridimensionata e in entrambi i casi non ha alcun layout del puntatore.
Funzionamento del motore NDR
Questa sezione descrive il comportamento del motore NDR.
Passaggio di marshalling
Strutture conformi e struttura conforme incorporata.
La struttura di primo livello si comporta come una struttura a livello singolo.
Struttura complessa incorporata con matrice conforme
Qualsiasi struttura complessa impone che la struttura esterna sia una struttura complessa. La struttura incorporata non effettua mai il marshalling della matrice. Ogni struttura passa sempre attraverso puntatori incorporati eseguendo semplicemente il marshalling dei membri e un membro che sta accadendo per essere un FC_POINTER.
Struttura complessa con struttura conforme
La struttura conforme più incorporato esegue il marshalling della matrice conforme e di tutti i puntatori conformi. Il motore NDR non scende mai a strutture conformi annidate più profonde, se presenti; questo semplifica la soluzione, poiché una struttura conforme è un oggetto foglia per quanto riguarda il marshalling di oggetti incorporati. La struttura complessa di primo livello ignora il marshalling della matrice.
Unmarshaling, bufsizing e freeing pass
Unmarshaling è simmetrico per il marshalling; La prima operazione eseguita per strutture complesse consiste nel individuare la posizione dei punti nel buffer chiamando la funzione NdrComplexStructBufferSize . Viene quindi annullata l'associazione dei puntatori in parallelo, consentendo lo stesso schema per l'annullamento delmarshamento dei puntatori. Non dovrebbe esserci confusione sugli oggetti e le unioni ridimensionati; L'immagine di memoria non deve essere usata per oggetti e unioni di dimensioni, solo per il contenuto del buffer.
I flag usati per eseguire correttamente il marshalling e l'annullamento del marshalling vengono usati nello stesso modo in cui vengono eseguiti il bufsizing e liberando per assicurarsi che i puntatori vengano camminati esattamente una volta.
Passaggio di endianità
In un primo momento, il passaggio di endianness è un po 'simile al marshalling/unmarshaling; per elaborare strutture complesse sono necessari due passaggi. Il primo passaggio converte la parte piatta e trova la posizione dei puntatori nel buffer in modo simile al modo in cui il bufsizing esegue questa operazione per l'annullamento delmarshaling. Il secondo passaggio converte quindi i puntatori.
I passaggi endianness differiscono nel modo seguente: ogni struttura e ogni membro deve essere rientri fino a quando il membro o l'elemento foglia non è un tipo semplice. Questo è diverso dall'unmarshaling; in unmarshaling, ad esempio, non è mai necessario elaborare strutture conformi incorporate in strutture conformi, o qualsiasi membro della struttura conforme, per tale questione. Un altro problema è che la conversione non è un'operazione idempotente, quindi il passaggio di annullamento delmarshaling di alcuni pezzi senza danni, mentre la conversione deve essere eseguita in modo rigorosamente una volta per ogni tipo semplice.
Di conseguenza, l'algoritmo endianness può essere riepilogato come segue. Il rapporto di mancato recapito ha una nozione della struttura conforme di primo livello e un flag per contrassegnarlo, in base alle esigenze. Quando si cammina per la prima volta, ad esempio per convertire la parte piatta e per ottenere la posizione dei puntatori, questa nozione non verrà usata. Il rapporto di mancato recapito scende attraverso le parti piane di tutti i livelli di strutture e non si avventura mai nell'elaborazione dei puntatori. Infine, il rapporto di mancato recapito converte la matrice al livello superiore.
Quando si cammina per la seconda volta, la bandiera viene usata per contrassegnare il passaggio del puntatore incorporato per evitare di entrare in livelli più profondi delle strutture conformi, quindi la struttura più conforme. In questo modo, il flag forza il comportamento comune di marshalling/unmarshaling, che consiste nell'evitare la decrescente in livelli più profondi di strutture conformi.
Il secondo passaggio per strutture complesse con matrici conformi funziona come segue: le strutture complesse funzionano in modo comune; questo significa che i livelli più profondi non esaminerebbero mai o ignorano le dimensioni conformi o le loro matrici conformi e preferirebbero semplicemente camminare i loro membri senza toccare la matrice.
Per strutture complesse con strutture conformi, la struttura conforme deve essere consapevole se è di primo livello e se si trova in una struttura complessa. La parte piatta della matrice viene elaborata dalla struttura più conforme. Al secondo passaggio, la struttura più conforme all'inizio ignora la parte piatta e passa attraverso il layout del puntatore e restituisce. La struttura più complessa ignora la parte piatta e ignora anche il layout del puntatore.
L'aspetto robusto delle passeggiate endianness
La procedura di endianness verifica la presenza delle normali condizioni fuori buffer ed esegue altri controlli di natura non correlata. I controlli volti a valori correlati (ad esempio l'argomento di ridimensionamento rispetto alle dimensioni conformi) non possono essere eseguiti usando questo passaggio; vengono eseguite in un secondo momento, quando non si separano.