First off, I'm brand new (as in 1-2 weeks in) to C#. I'm trying to wrap WinDivert methods for use inside C# and I've been having mixed success and failure. Though I'm not sure, I believe I've narrowed down the issue to a misalignment (literally) between how certain structs are defined in the unmanaged code and how they are defined in C#, due to (as far as I know) a limitation of C#.
And example from https://github.com/basil00/Divert/blob/master/include/windivert.h
typedef struct
{
UINT8 HdrLength:4;
UINT8 Version:4;
UINT8 TOS;
UINT16 Length;
UINT16 Id;
UINT16 FragOff0;
UINT8 TTL;
UINT8 Protocol;
UINT16 Checksum;
UINT32 SrcAddr;
UINT32 DstAddr;
} WINDIVERT_IPHDR, *PWINDIVERT_IPHDR;
This is one of the structure I'm having an issue translating. As you can see, HdrLength and Version are defined to occupy 4 bits of the structure each. In the C# version, I've tried simply declaring byte HdrLengthAndVersion, I've tried changing layout to explicity and manually defining the position of the members so that they overlap in cases like this to ensure the same memory length and position, etc. This gets exceptionally complicated with some of the other, larger structs.
I'm curious if there is any way to properly translate this to C#? I'm also curious if this is even possible, or if it will be an issue on different architectures. I know that we're getting in to memory alignment, padding etc here which I'll admit is currently a topic I'm less than an expert on, which is why I'm here :).
As a second option, I'm considering just doing some void pointers (since the managed stuff allocates and works with these objects) and just shifting position then type casting the pointer back to the specific values I actually need to access. But again, not sure if this possible.
Also just for the sake of mentioning, I've tried SWIG. Didn't work, I get 998 ERROR_NOACCESS errors when trying to use it so, just a huge heap of classes I didn't write with more problems.