致投反对票的人:这个答案解决了两个问题:调用约定/调用约定的直接问题MarhsalAs
属性,以及他很快就会发现的问题TTest
如果他接受我的转向建议,参数将不起作用TTest
到一个结构体中。
您的本机代码要求void*
,在 C# 中是IntPtr
。首先你应该定义TTest
作为结构而不是类。其次,你应该改变声明Foo
to:
[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(IntPtr lplf);
第三,你应该固定TTest
使用fixed
关键字并将其指针传递给Foo
。如果您使用的是类,则可以使用Marhsal.StructureToPtr
得到一个IntPtr
从你的TTest
.
这在两侧提供了相同的功能,可以传入指向任何类型的指针。您还可以使用要使用的所有类类型编写重载,因为它们都等同于void*
在本机方面。对于结构体,您的参数将前面加上一个ref
.
我很好奇的是为什么你的本机代码想要一个void*
代替TTest*
当您在非托管代码中执行的第一件事被转换为TTest*
。如果您将参数切换为TTest*
,那么提供相同的功能就变得更简单。你的声明将变成:
[DllImport(@"C:\.net course\unmanaged1\unmanaged3\Debug\unmanaged3.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern void Foo(ref TTest lplf);
你可以将该函数称为Program.Foo(ref Test);
如果您正在使用该类,则ref
不是必需的,因为类是引用类型。