2016-07-01 10 views
0

У меня есть библиотеки DLL осуществления LZ4 с и я хочу, чтобы вызвать функциюПередача массив символов из C# для C++ DLL

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

из C# кода. Функция сжимает исходный массив в массив dest. Как это сделать?

Мой C# код:

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

Должно быть неподписанным char *. Какой аспект этого вы не можете сделать. –

+0

Проблема с передачей массива dest по ссылке. Сжатый массив написан dll. Но я не получаю изменения на стороне C#. –

+0

'[Out] byte [] dest' и, очевидно, вам нужно выделить' dest', прежде чем вы вызовете функцию –

ответ

1

Ваш код имеет ряд ошибок:

  • бессмысленно устанавливать CharSet, так как нет никакого текста здесь.
  • Вы указываете SetLastError как true, но я сомневаюсь, что ваша функция C вызывает функцию Win32 SetLastError.
  • В C# char - 2-байтовый текст, содержащий элемент символа UTF-16. Это не пакет C char или unsigned char, которые являются 8-разрядными типами.
  • Ваш код ожидает, что функция C выделит управляемый byte[], поскольку массив байтов объявлен как параметр out. Ваш код C не может выделить управляемый byte[]. Вместо этого вам нужно, чтобы вызывающий абонент выделил массив. Таким образом, параметр должен быть [Out] byte[] dest.

код C следует использовать unsigned char, а не char, потому что вы работаете на двоичном, а не текст. Оно должно быть:

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

Совпадение C# P/Invoke является:

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

Зов это следующим образом:

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

Я догадался, возвращаемый тип функции, потому что вы пропустили это в декларации C, но ваш код C# предполагает, что это int.

+0

Я опубликовал код. Мне интересно, почему я получаю исключение нарушения доступа –

+0

Поскольку у вашего кода есть различные ошибки, как я описал. Моя последняя маркерная точка - самая правдоподобная причина для АВ. Я предполагаю, что вы, возможно, не понимаете, что 'out byte [] dest' и' [Out] byte [] dest' совершенно разные. –

+0

Да, я пропустил это. Спасибо. Это была отличная помощь. Большое спасибо. Я не знаком с C#, поэтому я столкнулся с проблемой. Спасибо большое. –