Avatar billede connorz Nybegynder
05. oktober 2006 - 15:42 Der er 10 kommentarer og
1 løsning

Import fra unmanaged kode

Hej eksperter

Jeg har følgende funktion i C (defineret i en dll (beagle.dll)):

Beagle c_beagle_open_ext (
    int        port_number,
    BeagleExt * beagle_ext
);

hvor BeagleExt er en struct defineret ved:

struct BeagleExt {
    BeagleVersion version;
    int          features;
};

hvor BeagleVersion er en struct, der blot indeholder en masse ints.

Jeg vil gerne benytte c_beagle_open_ext i C#, så jeg gør følgende:

[DllImport("beagle.dll")]
private static extern int c_beagle_open_ext(int port_number, ref BeagleExt beagle_ext);

Her er BeagleExt en struct i C#, der er defineret nøjagtigt som i C (og med [StructLayout(LayoutKind.Sequential)])

Jeg kalder nu min eksterne funktion med:

BeagleExt be = new BeagleExt();
c_beagle_open_ext(Port,ref be);

Dette går godt forstået på den måde, at den returnerede int er som forventet, og be indeholder den korrekte mængde ints i struct'en BeagleVersion, men features forbliver 0, mens det er forventet, at den skulle være 3. Denne værdi får jeg, hvis jeg kalder funktionen fra et C program. Hvis jeg sætter features til -1 inden kaldet til c_beagle_open_ext, er den også -1 bagefter! C-koden ændrer altså ikke værdien som den burde, og som den gør, når det er et rent C/C++ program.

Er der nogen, der kan give mig en forklaring på, hvad der er galt?!?!?
Avatar billede arne_v Ekspert
05. oktober 2006 - 15:45 #1
alignment/packing problem maaske ?
Avatar billede connorz Nybegynder
05. oktober 2006 - 15:48 #2
Du mener rækkefølgen på definitionen i structen? Ja den er tjekket og passer...
Avatar billede arne_v Ekspert
05. oktober 2006 - 15:56 #3
nej

jeg mener alignment/padding
Avatar billede arne_v Ekspert
05. oktober 2006 - 15:57 #4
eksempel:

struct foobar
{
  a char; // byte i C#
  b int;
}

kan implementeres som

1 byte
4 byte

eller

1 byte
3 filler bytes
4 bytes

eller diverse andre konmbinationer
Avatar billede connorz Nybegynder
05. oktober 2006 - 16:09 #5
hmm... structsene er erklæret som:
        [StructLayout(LayoutKind.Sequential)]
        private struct BeagleExt {
            public BeagleVersion version;
            public UInt32 features;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct BeagleVersion {
            public UInt16 software;
            public UInt16 firmware;
            public UInt16 hardware;
            public UInt32 hw_revs_for_sw;
            public UInt32 drv_revs_for_sw;
            public UInt16 api_req_by_sw;
        };

I C er der brugt u16 og u32 (som jeg går ud fra er defineret som hhv 16 og 32 bits unsigned integers)

Kan der så være noget galt her ift. det du skriver?
Avatar billede arne_v Ekspert
05. oktober 2006 - 16:28 #6
proev evt. med

[StructLayout(LayoutKind.Sequential, Pack=1)]

og

[StructLayout(LayoutKind.Sequential, Pack=4)]
Avatar billede connorz Nybegynder
06. oktober 2006 - 10:29 #7
Hmm... Det ser ud til at virke, når Pack=1 begge steder, men jeg forstår altså ikke helt hvorfor?! Alle de benyttede data er enten 2 eller 4 bytes, så hvor mange måder kan der lige være at lægge det i hukommelsen på? Det er compileren, der står for det ikke?

Smid et svar og du får nogle meget velfortjente point :)
Avatar billede connorz Nybegynder
06. oktober 2006 - 10:30 #8
Giver det en væsentlig performance nedsættelse, at man bruger Pack=1 ??

Og du må meget gerne forsøge at oplyse om, hvorfor det kan gøre forskellen... :)
Avatar billede arne_v Ekspert
06. oktober 2006 - 13:19 #9
den pakker som i første eksempel 05/10-2006 15:57:33
Avatar billede arne_v Ekspert
06. oktober 2006 - 13:19 #10
svar
Avatar billede arne_v Ekspert
06. oktober 2006 - 13:20 #11
hvis du har et array med en million elementer og der er noget i den som ligger
skævt så kan det koste rigtigt meget i performance - har du en enkelt struct med
noget som ligger skævt betyder det intet
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester