Avatar billede m_k_l Nybegynder
11. november 2003 - 14:23 Der er 15 kommentarer

Pointere i C#

Hej,
Jeg har et problem med noget kode, der burde kopiere indholdet af en tilfældig struct over i et byte array. Problemet er at hver gang jeg bruger funktionen bliver der overskrevet noget hukommelse andet steds i programmet så dette går ned. Hvad gør jeg galt ???


private static byte[] ConvertStructToByte( object anything, ref byte rawsize)
{
rawsize = (byte)Marshal.SizeOf( anything );
IntPtr buffer = Marshal.AllocHGlobal( rawsize );
byte[] rawdatas = new byte[ rawsize ];
Marshal.StructureToPtr( anything, buffer, true );
Marshal.Copy( buffer, rawdatas, 0, rawsize );
Marshal.FreeHGlobal( buffer );
return rawdatas;
}
Avatar billede finger Nybegynder
11. november 2003 - 15:04 #1
Jeg var ellers under det indtryk af at det ikke var nødvendigt at rode med pointere i c# medmindre man bruger win32 API (gør du det her?).
Men har du prøvet at pakke det ind i en unsafe code blok?
Måske det kan hjælpe?
Det er et vildt skud i tågen...
Avatar billede m_k_l Nybegynder
11. november 2003 - 15:12 #2
Jeg bruger ingen api kald, og har heller ikke prøvet at pakke det ind i en unsafe block. Vil det i så fald blive mere sikkert ???

Min case er at jeg har 12 forskellige structs (forskellige størrelse og type), disse skal sendes via COM porten, hvorfor jeg skal have dem konverteret til et byte array.
Alternativet til den ovensstående funktion ville vel være 12 forskellige funktioner der hver i sær konverterede den enkelte struct til et byte array.
Ovenstående funktion ville derfor være noget smartere (hvis den da virkede...)
Findes der måske en helt anden metode ???
Avatar billede finger Nybegynder
11. november 2003 - 15:20 #3
Det med unsafe code blok, er bare noget jeg forbinder med unmanaged code og poitere. Det kan sagtens tænkes at det intet har med det du laver at gøre.

Ud fra din beskrivelse tror jeg også det er det rigtige du prøver at gøre, men det er vist ude over min kunnen.
Avatar billede finger Nybegynder
11. november 2003 - 15:24 #4
mon ikke du kan bruge dette eller nogle af de links der er der:

http://www.csharp-station.com/ShowPost.aspx?PostID=1068
Avatar billede odegaard Nybegynder
11. november 2003 - 17:50 #5
Det er vel smartere at lave 12 forskellige klasser, i stedet for 12 structs. Så kan du samtidigt erklære ToByteArray funktioner for hver især. Det er ihvertfald den fede OOP måde at gøre det på.
Avatar billede arne_v Ekspert
11. november 2003 - 20:07 #6
Jeg kan ikke se nogen fejl i koden.

Der er et par små ting du skal være opmærksom på:

1)  hvis størrelsen af struct overskrider hvad der kan være i en byte
    så går det galt

2)  Konceptet giver mening ved int, double og lignende basale typer.
    Det resulterende bytes er meningsløse hvis der er string eller andre
    komplekse typer.
Avatar billede m_k_l Nybegynder
11. november 2003 - 21:42 #7
Der er kun typer at byte, ushort og int. De enkelte structs er defineret som følger:
[StructLayout(LayoutKind.Sequential, Pack=1)]
  struct Record
  {
  public byte year;
  public byte month;
  public byte day;
  [MarshalAs( UnmanagedType.ByValArray, SizeConst=24 )]
  public ushort[] power;
  }

ad 1)
Nogle af værdierne i f.eks. ushort overstiger 256, men ideen med ovenstående kode, er vel netop hele struct'en formateres til et byte array, som så kan "pakkes ud" i den anden ende af transmissionen.
Avatar billede arne_v Ekspert
11. november 2003 - 21:50 #8
Jeg snakker om hvis lægden af recorden ikke indholdet af recorden ikke
kan være i en byte.
Avatar billede arne_v Ekspert
11. november 2003 - 21:53 #9
Arrays duer heller ikke !

Et C# array er en C++ pointer d.v.s. den indeholde rkun 4 byte med en
adresse.

Og at kopiere en adresse et andet sted hen giver ikke mening.
Avatar billede arne_v Ekspert
11. november 2003 - 21:56 #10
Eller laver den MarshalAs noget smart ?
Avatar billede arne_v Ekspert
11. november 2003 - 22:16 #11
Lidt eksperimenteren viser at det gør den.
Avatar billede m_k_l Nybegynder
11. november 2003 - 22:31 #12
Jeps, selve kopieringen virker fint. Mit problem er at det ser ud som om der ligeledes bliver skrevet i/frigjort et andet hukommelsesområde, så min WinForm efter et kald til denne funktion lige pludselig kommer med en exception. Det underlige er at det ikke er hver gang :-/
Avatar billede arne_v Ekspert
11. november 2003 - 22:48 #13
Hm.

Jeg har prøvet at kalde den metode med 4 structs 1000 gange hver (alt 4000 gange).

Ingen fejl.

Pakker du ud igen i samme program ?
Avatar billede m_k_l Nybegynder
11. november 2003 - 22:59 #14
nope, der er et eksternt test program der læser dataene, når jeg har sendt dem via COM porten.
Synes umiddelbart heller ikke der burde være noget galt med funktionen.
Jeg benytter en ekstern komponent fra SAX til at sende skidtet via COM porten, det kan være jeg skal kigge lidt nærmere på den. :-/
Avatar billede arne_v Ekspert
30. november 2003 - 23:26 #15
Kommet videre ?
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