C ++ CLI struktur til byte array

stemmer
3

Jeg har en struktur som representerer en ledning format pakke. I denne strukturen er en rekke andre konstruksjoner. Jeg har generisk kode som håndterer dette veldig fint for de fleste tilfeller, men denne rekke strukturer saken kaster marshaller for en loop.

Usikre kode er en no gå siden jeg ikke kan få en peker til en struct med en rekke (argh!).

Jeg kan se fra denne codeproject artikkelen at det er en veldig fin, generisk tilnærming med C ++ / CLI som går noe sånt ...

public ref class Reader abstract sealed
    {
    public:
        generic <typename T> where T : value class
        static T Read(array<System::Byte>^ data)
        {
            T value;

            pin_ptr<System::Byte> src = &data[0];
            pin_ptr<T> dst = &value;

            memcpy((void*)dst, (void*)src,
                /*System::Runtime::InteropServices::Marshal::SizeOf(T::typeid)*/
                sizeof(T));

            return value;
        }
    };

Nå hvis bare hadde strukturen -> byte array / forfatter versjonen jeg ville bli satt! Takk på forhånd!

Publisert på 01/12/2008 klokken 04:23
kilden bruker
På andre språk...                            


5 svar

stemmer
2

Bruke memcpy å kopiere en rekke bytes til en struktur er ekstremt farlig hvis du ikke er kontrollerende byte pakking av strukturen. Det er tryggere å marshall og unmarshall en struktur ett felt om gangen. Selvfølgelig vil du miste den generiske funksjon i eksempelkoden du har gitt.

For å svare på ditt virkelige spørsmålet om (og vurdere dette pseudo-kode):

public ref class Writer abstract sealed
    {
    public:
        generic <typename T> where T : value class
        static System::Byte[] Write(T value)
        {
            System::Byte buffer[] = new System::Byte[sizeof(T)]; // this syntax is probably wrong.
            pin_ptr<System::Byte> dst = &buffer[0];
            pin_ptr<T> src = &value;

            memcpy((void*)dst, (void*)src,
                /*System::Runtime::InteropServices::Marshal::SizeOf(T::typeid)*/
                sizeof(T));

            return buffer;
        }
    };
Svarte 01/12/2008 kl. 05:16
kilden bruker

stemmer
1

Usikre kode kan gjøres for å gjøre dette, faktisk. Se mitt innlegg på lese structs fra disk: Reading arrays fra filer i C # uten ekstra kopi.

Svarte 14/02/2009 kl. 19:06
kilden bruker

stemmer
0

Har jeg gått glipp av noe? Hvorfor ikke skape en ny rekke av samme størrelse og initiere hvert element separat i en løkke?

Ved hjelp av en rekke byte data er ganske farlig med mindre du er målgruppe en plattform bare ... for eksempel metoden ikke anser ulik endianness mellom kilden og målet arrays.

Noe jeg forstår ikke helt om spørsmålet ditt også er grunnen til å ha en rekke som medlem i klassen som forårsaker et problem. Hvis klassen kommer fra et .NET språk bør du ha noen spørsmål, ellers bør du være i stand til å ta pekeren i usikre kode og initiere en ny rekke ved å gå gjennom elementene pekte på en etter en (med usikre kode) og tilsette dem til det.

Svarte 03/02/2009 kl. 13:57
kilden bruker

stemmer
0

Ikke endre strukturen er absolutt gode råd. Jeg bruker liberale mengder av StructLayout attributter for å angi pakking, oppsett og tegnkoding. Alt flyter helt fint.

Problemet mitt er bare at jeg trenger en performant og helst generisk løsning. Ytelse fordi dette er et serverprogram og generisk for eleganse. Hvis du ser på codeproject linken vil du se at de StructureToPtr og PtrToStructure metoder utfører i størrelsesorden 20 ganger tregere enn en enkel usikre peker cast. Dette er ett av de områdene hvor usikre kode er full av seier. C # vil bare la deg ha pekere til primitiver (og det er ikke generisk - kan ikke få en peker til en generisk), så det er derfor CLI.

Takk for psuedocode Grieve, vil jeg se om det får jobben gjort og rapportere tilbake.

Svarte 01/12/2008 kl. 21:14
kilden bruker

stemmer
0

Dette er sannsynligvis ikke den rette veien å gå. CLR er lov til å legge til padding, endre rekkefølgen på elementer og endre måten det er lagret i minnet.

Hvis du ønsker å gjøre dette, må du huske å legge [System.Runtime.InteropServices.StructLayout]attributt for å tvinge en bestemt minne layout for strukturen. Generelt, foreslår jeg at du ikke å rote med minne utformingen av .NET typer.

Svarte 01/12/2008 kl. 07:19
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more