I am trying to turn a pointer from a c dll into its equivelant C# struct array.
C Code
RECORD locked[MAX+1]; //MAX is a constant
typedef struct
{
State state; //enum
unsigned long allocated;
unsigned long lastUsed;
unsigned int useCount;
} RECORD;
API RECORD* __stdcall GetLocks( char* password )
{
if(strcmp(password, secret) == 0)
return locked;
else
return 0;
}
C# Code
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] // Pretty sure CharSet isnt actually needed here
public struct RECORD
{
public State state;
public UInt32 allocated;
public UInt32 lastUsed;
public UInt16 useCount;
}
[DllImport("gatewayapi.dll", CharSet = CharSet.Ansi)] // or here
static extern IntPtr GetLocks(string password);
public RECORD[] GetLocks(string password)
{
RECORD[] recs = new RECORD[MAX+1];
recs =(RECORD[])Marshal.PtrToStructure( GetLocks(password), typeof(RECORD[]));
if (recs.Length == 0)
{
throw new Exception();
}
return recs;
}
The above unfortunetly returns me a MissingMethodException -> No parameterless constructor defined for this object.
So in all im 100% new to Marshalling and would appreciate some advice on how to turn the pointer I receive from C into the actual C# struct array it represents.
Thanks
Given the originally posted C code, here is the answer I came up with that doesn't require compiling the code in unsafe mode:
[DllImport("gatewayapi.dll", CharSet = CharSet.Ansi)]
static extern IntPtr AMTgetLocks(string password);
public RECORD[] GetLocks(string password)
{
var channels = new RECORD[MAXCHANS + 1];
try
{
var c = AMTgetLocks(password);
var crSize = Marshal.SizeOf(typeof(RECORD));
for (int i = 0; i < MAXCHANS + 1; i++)
{
channels[i] = (CHANNELRECORD)Marshal.PtrToStructure(c, typeof(RECORD));
c = new IntPtr(c.ToInt64() + crSize);
}
}
catch (Exception)
{
throw new Exception();
}
if (channels.Length == 0)
{
throw new Exception();
}
return channels;
}
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