[英]How to Marshal C pointer to C# array of struct
我试图将一个指针从ac dll转换为其等效的C#结构数组。
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->没有为此对象定义无参数的构造函数。
因此,对于Marshalling来说,这是100%全新的知识,并希望获得一些有关如何将我从C接收到的指针转换为它所代表的实际C#结构数组的建议。
谢谢
给定最初发布的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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.