2011-12-30 9 views
6

ho trovato che l'implementazione della funzione GetBytes in .NET framework è qualcosa di simile:circa l'attuazione "GetBytes" in BitConverter

public unsafe static byte[] GetBytes(int value) 
{ 
    byte[] bytes = new byte[4]; 
    fixed(byte* b = bytes) 
    *((int*)b) = value; 
    return bytes; 
} 

io non sono così sicuro di capire i dettagli completi di questi due righe:

fixed(byte* b = bytes) 
    *((int*)b) = value; 

Qualcuno potrebbe fornire una spiegazione più dettagliata qui? E come dovrei implementare questa funzione in C++ standard?

risposta

4

Qualcuno potrebbe fornire una spiegazione più dettagliata qui?

La MSDN documentation for fixed viene fornito con numerosi esempi e spiegazioni - se questo non è sufficiente, allora avrete bisogno di chiarire che parte specifica non si capisce.


E come dovrei implementare questa funzione nello standard C++?

#include <cstring> 
#include <vector> 

std::vector<unsigned char> GetBytes(int value) 
{ 
    std::vector<unsigned char> bytes(sizeof(int)); 
    std::memcpy(&bytes[0], &value, sizeof(int)); 
    return bytes; 
} 
0

Corretto indica al garbage collector di non spostare un tipo gestito in modo che sia possibile accedere a quel tipo con puntatori standard.

In C++, se non si utilizza C++/CLI (vale a dire che non si utilizza .NET), è sufficiente utilizzare un puntatore (char) di dimensioni in byte e scorrere i byte in qualunque cosa si stia tentando di convertire.

Basta essere consapevoli di endianness ...

0

Prima fisso deve essere usato perché vogliamo assegnare un puntatore a una variabile gestita:

L'istruzione fixed impedisce il garbage collector da trasferire una variabile mobile . L'istruzione fissa è consentita solo in un contesto non sicuro . Risolto può essere utilizzato anche per creare buffer di dimensioni fisse.

L'istruzione fissa imposta un puntatore a una variabile gestita e "pin" tale variabile durante l'esecuzione dell'istruzione. Senza il prefisso, i puntatori per le variabili gestite mobili sarebbero di scarsa utilità dal momento che la raccolta di dati inutili può spostare le variabili in modo imprevedibile. Il compilatore C# consente di assegnare un puntatore a una variabile gestita in un'istruzione fissa .Ref.

Quindi dichiariamo un puntatore a byte e assegniamo all'inizio della matrice di byte.

Poi, gettiamo il puntatore al byte per un puntatore a int, dereferenziarlo e assegnarlo al Int passata.

0

la funzione crea un array di byte che contiene gli stessi dati binari come rappresentazione della vostra piattaforma di il numero intero value.In C++, ciò può essere ottenuto (per qualsiasi tipo veramente) in questo modo:

int value; // or any type! 
unsigned char b[sizeof(int)]; 
unsigned char const * const p = reinterpret_cast<unsigned char const *>(&value); 
std::copy(p, p + sizeof(int), b); 

Ora b è un array di tanti byte come la dimensione del tipo int (o qualsiasi tipo utilizzato).

In C# è necessario dire fixed per ottenere un puntatore raw, poiché di solito non si hanno puntatori grezzi in C# in considerazione di oggetti che non hanno una posizione fissa in memoria - il garbage collector può spostarli in qualsiasi momento . fixed impedisce questo e corregge l'oggetto in modo che un puntatore raw possa avere senso.

0

È possibile implementare GetBytes() per qualsiasi tipo di POD con un modello di funzione semplice.

#include <vector> 

template <typename T> 
std::vector<unsigned char> GetBytes(T value) 
{ 
    return std::vector<unsigned char>(reinterpret_cast<unsigned char*>(&value), 
             reinterpret_cast<unsigned char*>(&value) + sizeof(value)); 
} 
Problemi correlati