2016-07-01 43 views
0

Ich habe eine dll der LZ 4 c Implementierung und ich möchte dieÜbergabe eines char-Array von C# C++ dll

LZ4_compress_default(const char* source,char* dest,int sourceLength,int maxdestLength); 

Funktion aus einer C# -Code nennen. Die Funktion komprimiert das Quell-Array in das Ziel-Array. Wie macht man das?

Mein C# -Code:

DllImport(@"CXX.dll", CharSet = CharSet.Ansi, SetLastError = true, 
    CallingConvention = CallingConvention.Cdecl)] 
internal static extern int LZ4_compress_default(
    [MarshalAs(UnmanagedType.LPArray)] char[] source, out byte[] dest, 
    int sourceSize, int maxDestSize); 


byte[] result= new byte[maxSize]; 
int x = LZ4_compress_default(array, out result, size, maxSize); 
+0

Sollte unsigned char * sein. Welchen Aspekt können Sie nicht tun? –

+0

Problem, das Dest-Array durch Verweis übergeben.Das komprimierte Array wird von der DLL geschrieben. Aber ich bekomme nicht die Änderung in der C# -Seite. –

+0

'[Out] byte [] dest' und offensichtlich müssen Sie' dest' zuweisen, bevor Sie die Funktion –

Antwort

1

Ihr Code eine Reihe von Fehlern hat:

  • Es ist sinnlos CharSet zu setzen, da es keinen Text hier.
  • Sie geben SetLastError als true, aber ich bezweifle, dass Ihre C-Funktion ruft die Win32 SetLastError Funktion.
  • In C# char ist ein 2-Byte-Text, der ein UTF-16-Zeichenelement enthält. Das setzt C char oder unsigned char, die 8-Bit-Typen sind, nicht ab.
  • Ihr Code erwartet, dass die C-Funktion eine verwaltete byte[] zuweist, weil das Byte-Array als out Parameter deklariert ist. Ihr C-Code kann keine verwalteten byte[] zuordnen. Stattdessen muss der Anrufer das Array zuweisen. Also muss der Parameter [Out] byte[] dest sein.

Der C-Code sollte unsigned char verwenden, anstatt char, weil Sie auf binär arbeiten und nicht als Text. Es sollte sein:

int LZ4_compress_default(const unsigned char* source, unsigned char* dest, 
    int sourceLength, int maxDestLength); 

gesuchtes C# p/invoke ist:

[DllImport(@"...", CallingConvention = CallingConvention.Cdecl)] 
static extern int LZ4_compress_default(
    [In] byte[] source, 
    [Out] byte[] dest, 
    int sourceLength, 
    int maxDestLength 
); 

Nennen Sie es wie folgt aus:

byte[] source = ...; 
byte[] dest = new byte[maxDestLength]; 
int retval = LZ4_compress_default(source, dest, source.Length, dest.Length); 
// check retval for errors 

Ich habe bei der Rückgabetyp der Funktion erraten, weil Sie haben das in der C-Deklaration weggelassen, aber Ihr C# -Code deutet darauf hin, dass es int ist.

+0

Ich habe den Code geschrieben.Ich frage mich, warum ich Zugriffsverletzung Ausnahme –

+0

bekommen Da Ihr Code verschiedene Fehler hat, wie ich beschrieben habe. Mein letzter Punkt ist der plausibelste Grund für ein AV. Ich nehme an, dass Sie vielleicht nicht erkennen, dass 'out byte [] dest' und '[Out] byte [] dest 'völlig verschieden sind. –

+0

Ja, das habe ich verpasst. Danke. Das war eine große Hilfe. Danke vielmals. Ich bin nicht vertraut mit C#, also war ich mit dem Problem konfrontiert. Vielen Dank. –