Неуправляемая функция dll byte *, возвращаемая параметром в C # - PullRequest
2 голосов
/ 01 ноября 2010

Мне нужно использовать неуправляемую библиотеку VC ++.

Она имеет следующие две функции, для которых требуются оболочки C #:

bool ReadData(byte* byteData, byte dataSize);
bool WriteData(byte* byteData, byte dataSize);

Они обе возвращают true в случае успеха, но в противном случае возвращает false.

В настоящее время в C # у меня есть класс (WRAP) с функциями:

[DllImport("kirf.dll", EntryPoint = "ReadData", SetLastError=true)]
[return: MarshalAs(UnmanagedType.VariantBool)]
public static extern Boolean ReadData([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]out Byte[] bytesData, Byte dataSize);

[DllImport("kirf.dll", EntryPoint = "WriteRFCard", SetLastError = true)]
[return: MarshalAs(UnmanagedType.VariantBool)]
public static extern Boolean WriteRFCard[In]Byte[] bytesData, [In]Byte dataSize);

У меня есть

byte[] newData = new byte[17];
byte dataSize = 17;
bool result = WRAP.ReadData(out newData, dataSize);

Это всегда дает мне результат = false, newData= ноль, и не выдается ошибка (или, скорее, она всегда возвращается успешно).

И

byte[] bytesData = new Byte[] { (byte)0x9B, (byte)0x80, (byte)0x12, (byte)0x38, (byte)0x5E, (byte)0x0A, (byte)0x74, (byte)0x6E, (byte)0xE6, (byte)0xC0, (byte)0x68, (byte)0xCB, (byte)0xD3, (byte)0xE6, (byte)0xAB, (byte)0x9C, (byte)0x00 };
byte dataSize = 17; 
bool actual = WRAP.WriteData(bytesData, dataSize);

Есть какие-либо идеи относительно того, что я могу делать неправильно?

edit

Вот как мне в итоге это удалось:

        [DllImport("kirf.dll", EntryPoint = "ReadData", SetLastError=true)]
        [return: MarshalAs(UnmanagedType.VariantBool)]
        public static extern Boolean ReadData([Out] Byte[] bytesData, Byte dataSize);

[DllImport("kirf.dll", EntryPoint = "WriteData", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.VariantBool)]
        public static extern Boolean WriteData([In] Byte[] bytesData, Byte dataSize);

И:

Byte[] newData=new byte[17];
bool result = KABA_KIRF.ReadData(newData, (Byte)newData.Length);

и

bool result = KABA_KIRF.WriteData(data, datasize);

где данные были параметром Byte[], переданным в функцию.

1 Ответ

1 голос
/ 01 ноября 2010

Создает ли ReadData новый байтовый массив? В противном случае я не думаю, что bytesData должен быть out параметром.

Посмотрите на спецификацию PInvoke ReadFile для сравнения:

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadFile(IntPtr hFile, [Out] byte[] lpBuffer,
   uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);

lpNumberOfBytesRead - это выходной параметр, потому что ReadFile изменяет его значение. т.е. если вы передадите локальную переменную для lpNumberOfBytesRead, ReadFile изменит значение в стеке. С другой стороны, значение lpBuffer равно , а не изменено: оно все еще указывает на тот же байтовый массив после вызова. Атрибуты [In,Out] сообщают PInvoke, что делать с содержимым передаваемого массива.

...