P/Invoke 和 enums/structs 的 NativeMethods 约定

P/Invoke and NativeMethods convention for enums/structs

进行 pinvoke 时,惯例是将它们放在 NativeMethods class 中,但是请记住,枚举和结构都不需要放在 class 中,枚举的惯例是什么和 pinvoke 使用的结构?

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

我想对于 pinvoke 使用的常量也可以这样说,约定是否也将它们放在 NativeMethods 中 class?

此外,pinvoke 函数使用的结构、枚举和常量的命名约定是什么?在 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 class 里面吗?

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

当您在 Microsoft 的基础程序集上工作时,这样做有些有意义,它减少了声明重复的可能性,并且 pinvoke 声明可能被多次使用在不同 classes 的时间。 .NET 框架程序集有很多 pinvoke 代码。迫使 Microsoft 程序员考虑安全性也很重要。然而,它们仍然会重复,不同的基础程序集每个都有自己的一组 pinvoke 声明,并且它们经常彼此不一致。在命名上也是safe/unsafe的选择。不是很漂亮,但是让不同的团队在框架的不同部分工作是不可避免的副作用。

这些相同的规则不适用于像我们这样的凡人。应尽可能避免使用 Pinvoke。任何声明的一个很好的范围是 private,一个尽可能隐藏的实现细节,最好尽可能接近使用它的代码。但是,如果您喜欢使用代码分析并且不想维护自己的规则集,那么您将不得不按照 Microsoft 的方式进行操作。

最明智的做法是采用您团队的编码指南并有一个匹配的规则集来执行它。在这一点上,你可以做任何你想做的事情,并得到团队的同意。标识符名称大小写也是如此。我 个人 总是 copy/paste 从 SDK 头文件中,避免很难诊断错误的最佳方法。并且从来没有找到重命名标识符的充分理由,编译器不在乎,并且声明与普通声明根本不同,这让我有充分的理由让它看起来也有所不同。但这只是我个人的喜好,我无法帮助您自行决定。