1

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

4 回答 4

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);
于 2010-12-09T00:24:11.707 回答
0

亚当·内森的书是这方面的圣经

等等:这个函数的返回值到底是什么。它指向什么?

测试点到随机地址,然后在测试点处戳数据

你想返回什么?

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

于 2010-12-09T00:18:55.810 回答
0

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

您可能想尝试并接受一个IntPtr结果,然后使用Marshal该类来复制数据。

于 2010-12-09T00:19:10.427 回答
0

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

http://clrinterop.codeplex.com/

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

于 2010-12-09T00:24:32.737 回答