如何将C指针指向C#的struct数组

时间:2014-06-10 15:19:52

标签: c# c++ c marshalling

我正在尝试将指针从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#结构数组提出一些建议。

由于

1 个答案:

答案 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;
    }