C # вызов неуправляемого кода - PullRequest
1 голос
/ 09 декабря 2010

Я пытаюсь вызвать неуправляемый код с использованием C #.

extern "C" __declspec(dllexport) LPBYTE DataReceived(LPBYTE signals)
{
   LPBYTE test;
   *(WORD*)(test) = 0x0C;
   *(WORD*)(test + 2) = 0x1000;

   return test;
   // I even tried returning 0x00 only; and I was still getting the exception

}

C # code

internal sealed class Test
{
    [DllImport("testlib.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern byte[] DataReceived(byte[] signals);

}

// signals is byte[] too
byte[] foo = Test.DataReceived(signals);

//exception that occurs 
 A first chance exception of type 'System.Runtime.InteropServices.MarshalDirectiveException

У меня есть другая функция, которая прекрасно возвращает значение int, я думаю, этосамому LPBYTE.Цени любую помощь.

Ответы [ 4 ]

3 голосов
/ 09 декабря 2010

Я считаю, что вы хотите использовать

internal sealed class Test
{
    [DllImport("testlib.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
    public static extern IntPtr DataReceived(byte[] signals);

}

Обратите внимание, что при вызове вам нужно будет использовать Marshall.Copy для вывода данных, но для этого потребуется знать длину данных.

IntPtr fooPtr = Test.DataRecieved(signals);
var foo = new byte[LENGTH];
Marshall.Copy(fooPtr, foo, 0, LENGTH);
0 голосов
/ 09 декабря 2010

Вы должны проверить помощника взаимодействия pinvoke здесь:

http://clrinterop.codeplex.com/

Он автоматически сгенерирует подписи pinvoke для вас.

0 голосов
/ 09 декабря 2010

Как маршаллеру .NET узнать, сколько данных необходимо скопировать из возвращенного массива в экземпляр управляемого массива?

Вы можете попытаться принять IntPtr в качестве результата, а затем использовать класс Marshal для копирования данных.

0 голосов
/ 09 декабря 2010

Книга Адама Натанса - это Библия на этом

Подожди: что именно является возвращаемым значением этой функции. Это указатель на что?

контрольные точки на случайный адрес, затем вы кладете данные, где контрольные точки

Что вы хотите вернуть?

Если вы должны вернуть указатель, затем объявить функцию как возвращающую intptr, затем вызвать Marshall для копирования байтов. Затем вам нужно решить, нужно ли освобождать возвращенный буфер

...