C#调用非托管代码

时间:2010-12-09 00:14:08

标签: c# unmanaged return lpbyte

我正在尝试使用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#代码

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 个答案:

答案 0 :(得分:3)

我相信你想用

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);

答案 1 :(得分:0)

adam nathans书是本书的圣经

挂起:这个函数的返回值究竟是什么。它指向什么?

测试点到随机地址,然后你将数据戳到测试点

你想回来什么?

如果必须返回指针,则将函数声明为返回intptr,然后调用Marshall复制字节。那么你需要决定是否需要释放返回的缓冲区

答案 2 :(得分:0)

.NET编组器应该如何知道需要将多少数据从返回的数组复制到托管数组实例中?

您可能希望尝试接受IntPtr作为结果,然后使用Marshal类复制数据。

答案 3 :(得分:0)

您应该在这里查看pinvoke互操作助手:

http://clrinterop.codeplex.com/

它会自动为您生成pinvoke签名。