繁体   English   中英

封送C和C#

[英]marshalling C and C#

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

[DllImport=(Core.dll, SetLastError=true, EntryPoint="CoreCreate", CharSet="CharSet.Ansi", CallingConvention="CallingConvention.Cdecl")]
internal static extern uint CoreCreate(ref IntPtr core);
  1. 为什么需要“内部静态外部” 这是强制性的吗? 为什么要使用它?
  2. 什么是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之前声明,则内存布局在B之前具有A )。 这在声明顺序很重要的C语言中是不正确的(声明由编译器用来理解内存中原始数据的布局)。 如果必须与C函数互操作,则必须确定传递它们的数据的布局。 这就是LayoutKind.Sequential工作方式:它指示编译器遵守struct数据的声明顺序。 这不是与非托管环境互操作的唯一选项,您甚至可以显式设置每个字段的偏移量(从结构开始)(请参见LayoutKind.Explicit)。

这不是一个答案,只有几点评论:调用外部dll时,“内部静态”是一回事,而“外部”则是另一回事。 SetLastError或GetLastError是我们在过去的日子中经常使用的方法,用于从Windows获取有关最新处理的错误消息。 LayoutKind.Sequential是一种通知编译器以指定方式布局结构的方法-如果进入其他系统,则可能需要这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM