我正在尝试将指针从c dll转换为等效的C#struct array。
C代码
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#代码
[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;
}
上面不幸地给我发了一个MissingMethodException - >没有为此对象定义无参数构造函数。
所以我对100%的新编组很新,并且会对如何将我从C接收的指针转换为它所代表的实际C#结构数组提出一些建议。
由于
答案 0 :(得分:0)
鉴于最初发布的C代码,以下是我提出的答案,不需要在不安全模式下编译代码:
[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;
}