Gå til innhold

Anbefalte innlegg

Videoannonse
Annonse

Vel... to ting du må tenke på: calling convection og export library.

Calling convection er stdcall i Windows (og C#) men C bruker cdecl.

Eksempel:

C kode kompileres til hello.dll med Visual C++

extern "C"
{
 __declspec(dllexport) void __stdcall HelloStr(char* outp, int maxlen)
 {
   strcpy(outp, "Hello World!", maxlen);
 }
}

 

C#:

public static class Imports
{
 [system.Runtime.InteropServices.DllImport("hello")]
 public static extern void HelloStr(byte[] outp, int maxlen);
}

Lenke til kommentar

Du må oversette headeren. Det finnes sikkert verktøyer for å gjøre dette på internett, ettersom det er en temmelig enkel og rett frem sak.

Hvis ikke, så er det ikke stress å gjøre det selv. Ofte kan du bruke notepad og find/replace for å gjøre dette, men det krever at du forstår både C og C# godt.

Lenke til kommentar

Okay, da var jeg kommet ett skritt lengre, men er fortsatt ikke helt i mål.

 

Trur jeg har klart å lage Dll-fila og importere den riktig med denne koden:

 

[DllImport("Smaz.dll")]

public static extern int smaz_compress(IntPtr instring, int inlen, IntPtr outstring, int outlen);

 

Har altså bytta ut char* med IntPtr her, som jeg mener skal være riktig. (får jo feil hvis jeg prøver å bruke char* i C#). Problemet kommer når jeg prøver å gjøre om String til IntPtr tror jeg...

 

IntPtr i = Marshal.StringToHGlobalUni(Text);

IntPtr o = new IntPtr();

Compress.smaz_compress(i, 1024, o, 1024);

return Encoding.UTF8.GetBytes(o.ToString());

 

Får en MemoryAllocationError eller noe i den dur, sier at den prøver å skrive til protected memory og at dette er et tegn på at minnet er korrupt. Er det noe jeg gjør feil her?

Lenke til kommentar

Fnodig. Du kan se om noen av MarshalAs attributtene kan hjelpe, men jeg tviler.

Allokerer biblioteket minnet du får tilbake? Hvis ikke, må du sannsynligvis allokere det for den. Bruk Marshal.AllocHGlobal for dette.

Edit: hvis bbiblioteket gjør det, så har biblioteket også funksjoner for å frigjøre, ettersom en bit som er mallocet i en .dll kan ikke free-es av en annen .dll eller .exe.

Endret av GeirGrusom
Lenke til kommentar

Ok, fant ut at biblioteket ikke allokerte minnet for meg, så jeg brukte AllocHGlobal som du sa, still no luck...

 

Koden ser nå sånn ut:

 

       protected override byte[] EncodeData()
       {
           IntPtr stringToCompress = Marshal.StringToHGlobalUni(Text);
           IntPtr compressedString = new IntPtr(1024);
           Marshal.AllocHGlobal(stringToCompress);
           Marshal.AllocHGlobal(compressedString);
           Compress.smaz_compress(stringToCompress, Text.Length, compressedString, Text.Length*2);
           return Encoding.UTF8.GetBytes(compressedString.ToString());
       }

 

Skjønner ikke dette...

Lenke til kommentar

Må slutte å programmere etter sengetid :p

 

Du hadde selvfølgelig rett, og nå fungerer det som fjell! Tusen hjertelig takk for hjelpa :)

 

For de som er interessert, koden er nå:

 

protected override byte[] EncodeData()
       {
           IntPtr stringToCompress = Marshal.AllocHGlobal(Strings.Length);
           IntPtr compressedString = Marshal.AllocHGlobal(Strings.Length*2);
           Compress.smaz_compress(stringToCompress, Strings.Length, compressedString, Strings.Length * 2);
           return Encoding.UTF8.GetBytes(compressedString.ToString());
       }

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...