枚举/结构的P / Invoke和NativeMethods约定

时间:2016-06-05 12:15:04

标签: c# enums pinvoke

在执行pinvokes时,惯例是将它们放在NativeMethods类中,但是请记住,枚举和结构都不需要在类中,pinvoke使用的枚举和结构的约定是什么? / p>

它是否也将它们放在NativeMethods类中,在一个单独的类中,根本没有类?

我认为对于pinvoke使用的consts可以说同样的,也是将它们放在NativeMethods类中的约定?

此外,命名pinvoke函数使用的结构,枚举和consts的约定是什么?在C ++中,它们将被定义为类似CREATE_VIRTUAL_DISK_VERSION的东西,是保持它完全原样或将它们转换为C#标准的惯例,在这种情况下会使它成为CreateVirtualDiskVersion

修改

为了更清楚的示例,让我们使用以下结构,如MSDN中所定义并由本机函数ExpandVirtualDisk使用:

typedef struct _EXPAND_VIRTUAL_DISK_PARAMETERS {
  EXPAND_VIRTUAL_DISK_VERSION Version;
  union {
    struct {
      ULONGLONG NewSize;
    } Version1;
  };
} EXPAND_VIRTUAL_DISK_PARAMETERS, *PEXPAND_VIRTUAL_DISK_PARAMETERS;

在C#中声明这个以便它可以作为参数传递给ExpandVirtualDisk本机函数时,你会将它声明为......

public struct EXPAND_VIRTUAL_DISK_PARAMETERS
{
    public EXPAND_VIRTUAL_DISK_VERSION Version;
    (...)
}

或类似......

public struct ExpandVirtualDiskParameters
{
    public ExpandVirtualDiskVersion Version;
    (...)
}

你会把它放在NativeMethods班吗?

1 个答案:

答案 0 :(得分:3)

这个pinvoke声明应该在Un / SafeNativeMethods类中,是Microsoft程序员的编码指南。不幸的是,当他们发布了用于执行编码指南的工具时,该规则被泄露出来,以前称为FxCop。

当您在基础程序集上为Microsoft工作时,它会使某些有意义,它降低了声明重复的可能性,并且pinvoke声明可能会在不同的类中多次使用。 .NET框架程序集有很多pinvoke代码。迫使Microsoft程序员考虑安全性也非常重要。然而,它们仍然是重复的,不同的基本组件每个都有自己的pinvoke声明集,并且它们经常彼此不一致。在命名和安全/不安全的选择。不是很漂亮,但让不同的团队在框架的不同部分工作会产生一些不可避免的副作用。

这些规则并不适用于像我们这样的凡人。应尽可能避免使用Pinvoke。任何声明的良好范围是private,这是一个尽可能隐藏的实现细节,最好尽可能接近使用它的代码。但是如果你想使用代码分析并且不想维护自己的规则集,那么你几乎不得不以微软的方式去做。

最明智的方法是采用您团队的编码指南,并使用匹配的规则集来强制执行。此时,您可以做任何您想做的事情并得到团队的同意。标识符名称 - 外壳大致相同。我个人总是从SDK头文件中复制/粘贴,这是避免很难诊断错误的最佳方法。而且从来没有找到一个重命名标识符的好理由,编译器并不关心,并且声明与普通声明根本不同,这给了我一个很好的理由让它看起来不同。但这只是我个人的偏好,我不能帮你自己决定。