我的项目中有以下编组代码。我对此几乎没有疑问。

[DllImport=(Core.dll, SetLastError=true, EntryPoint="CoreCreate", CharSet="CharSet.Ansi", CallingConvention="CallingConvention.Cdecl")]
internal static extern uint CoreCreate(ref IntPtr core);



为什么需要“内部静态外部”?这是强制性的吗?为什么要使用它?
什么是SetLastError?



[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Ansi)]
internal struct Channel
{
internal byte LogicalChannel;
}



为什么选择LayoutKind.Sequential?

最佳答案

为什么需要“内部静态外部”?


internal修饰符只是设置方法的可见性。不需要是internal,因此您可以根据需要以及与其他任何标准方法一样声明方法privatepublic

static修饰符是必需的,因为它不是实例方法,并且该方法不知道任何类(它没有this指针)。

最后,需要extern通知编译器该方法不是在这里实现的,而是在另一个地方实现的(您将在哪里指定使用属性的位置)。 Evey extern方法也必须声明为static(因为这是一个简单的函数调用,没有任何对象知识)。


  什么是SetLastError?


这表明该方法可能会更改线程的最后错误代码值。有关详细信息,请参见GetLastError()函数。如果被调用的函数将更改此值,那么将MSDN中的SetLastError设置为true是一件好事:


  运行时封送处理程序调用GetLastError并缓存返回的值,以防止其他API调用覆盖它。您可以通过调用GetLastWin32Error来检索错误代码。


简而言之,它将GetLastError()返回的值保存到内部缓存中,因此对系统API的任何其他调用(甚至是其他框架函数的内部调用)都不会覆盖该值。


  为什么选择LayoutKind.Sequential?


.NET中的类布局不需要在内存中是顺序的(顺序=如果AB之前声明,则内存布局在A之前具有B)。这在声明顺序很重要的C语言中是不正确的(声明由编译器用来理解内存中原始数据的布局)。如果必须与C函数互操作,则必须确定传递它们的数据的布局。 LayoutKind.Sequential是这样工作的:它指示编译器遵守struct中数据的声明顺序。这不是与非托管环境互操作的唯一选项,您甚至可以显式设置每个字段的偏移量(从结构开始)(请参见LayoutKind.Explicit)。

10-06 01:46