c# - C/C++ 与 C# 的互操作性命名约定

标签 c# c++ c winapi pinvoke

考虑以下 Win32 API 结构:

typedef struct _SECURITY_ATTRIBUTES {
  DWORD  nLength;
  LPVOID lpSecurityDescriptor;
  BOOL   bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;

当将此对象移植到 C# 时,我是否应该遵循此处使用的名称命名约定,如下所示:

public struct _SECURITY_ATTRIBUTES
{
    public int nLength;
    public unsafe byte* lpSecurityDescriptor;
    public int bInheritHandle;
}

或者我可以全力以赴,用 C# 风格编写我的结构,如下所示:

public struct SecurityAttributes
{
    private int length;
    private unsafe byte* securityDescriptor;
    private int bInheritHandle;

    public Int32 Length
    {
        get { return this.length; }
        set { this.length = value; }
    }

    public Byte* SecurityDescriptor
    {
        get { return this.seurityDescriptor; }
        set { this.securityDescriptor = value; }
    }

    public Int32 InheritHandle
    {
        get { return this.bInheritHandle; }
        set { this.bInheritHandle = value; }
    }

    public SecurityAttributes(int length, byte* securityDescriptor, int inheritHandle)
    {
        this.length = length;
        this.securityDescriptor = securityDescriptor;
        this.inheritHandle = inheritHandle;
    }
}

虽然第二种方法看起来更优雅,但我想知道是否建议使用以这种方式编写的结构调用 native 功能,或者从 C/C++ 移植结构时是否存在任何其他陷阱。

最佳答案

这取决于您的个人喜好。您选择哪种方法的主要考虑因素应该是易于代码维护。就我个人而言,我倾向于坚持使用与 C 声明中使用的名称完全相同的名称,因为这样更容易理解我在看什么。例如,如果我这样定义一个结构:

/// <summary>
/// Unmanaged sockaddr_in structure from Ws2def.h.
/// </summary>
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct sockaddr_in
{
    /// <summary>
    /// short sa_family;
    /// </summary>
    public short sa_family;

    /// <summary>
    /// unsigned short sin_port;
    /// </summary>
    public ushort sin_port;

    /// <summary>
    /// struct in_addr addr;
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 4)]
    public byte[] addr;

    /// <summary>
    /// char sin_zero[8];
    /// </summary>
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 8)]
    public byte[] sin_zero;
}

然后我或同事想知道 sa_family 到底是什么,我们可以搜索有关 sa_family 的文档。如果我有一个 Family 属性,我将有一个额外的步骤来确定它映射到 sa_family。

当然,我可以将命名良好的 getter 和 setter 放在结构上,例如 public short Family... 但是,我尝试将互操作结构和方法隐藏在更易于使用的后面界面。似乎没有必要扩展低级互操作定义。

关于c# - C/C++ 与 C# 的互操作性命名约定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13957362/

相关文章:

c++ - 调试断言失败表达式 : _pFirstBlock == pHead using OpenCV and C++ trying to call SurfFeatureDetector

c++ - 编译器优化返回 (std::stringstream ss).str()

c - 在文本文件中搜索字符串,以空格分隔并截断空格后的所有内容

c - 警告 : assignment makes integer from pointer without a cast, 排序参数

c# - 将复选框列表传递到 View 中并拉出 IEnumerable

c# - 无法加载文件或程序集“Microsoft.Practices.EnterpriseLibrary.Caching”

c# - 使用 FlurlClient 的自定义 HttpClientHandler 不使用 ClientCertificate

c++ - 如何强制我的应用程序出现在最前面并获得焦点?

c - 在 C 中使用限制关键字的规则?

c# - 扩展方法可以有泛型参数吗?