Consider the following Win32 API struct:
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
When porting this object to C#, should I follow the name naming conventions used here, like so:
public struct _SECURITY_ATTRIBUTES
{
public int nLength;
public unsafe byte* lpSecurityDescriptor;
public int bInheritHandle;
}
or can I go all out, and write my struct in a C# style, like so:
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;
}
}
Whilst the second approach seems much more elegant, I would like to know if it is advisable to invoke native functionality using a struct written in that fashion, or if there are any other pitfalls when porting structs from C/C++.
This comes down to your personal preference. Your primary consideration in which approach to chose should be ease of code maintenance. Personally, I favor sticking with the exact same names as those used in the C declaration, because it makes it easier to understand what I'm looking at. For example, if I define a struct like so:
/// <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;
}
Then later I or a co-worker want to know just what the heck sa_family
is, we can just search for documentation on sa_family. If I instead had a Family property, I would have the extra step of figuring out that it maps to sa_family.
Of course, I could put nicely named getters and setters on the struct, e.g., public short Family...
However, I try to hide interop structs and methods behind an easier-to-use interface. Spiffing up the low-level interop definitions just doesn't seem necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With