编组从C#嵌套结构到C ++(Marshaling nested structures from C

2019-10-22 06:52发布

我在C ++以下几种类型:

typedef void* keychain_handle;

typedef struct {
  const char* keyHolderName;
  unsigned int numKeys;
  key* keys;
} key_holder;

typedef struct {
  const char* keyName;
  unsigned int keySize;
} key;

我有以下methos:

int createKeyChain(
  int id, 
  key_holder* keyHolders,
  keychain_handle* handle);

我需要我的C#创建密钥持有人键,将它发送到C ++代码,并收到一个手柄。

这是我的C#代码:

    /* Structs */
    [StructLayout(LayoutKind.Sequential)]
    public struct Key
    {
          public string key;
          public uint size;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct KeyHolder
    {
          public string name;
          public uint keys;
          public IntPtr keys;
    }


    /* Sync API */
    [DllImport("keys.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
    public static extern uint createKeyChain(uint id, KeyHolder[] keyHolders, ref IntPtr handle);


        Key[] myKeys = new Key[1];
        myKeys[0] = new Key { key = "tst", size = 5 };

        KeyHolder keyHolder = new DllWrapper.KeyHolder
        {
            name = "tst123",
            items = 1,
            keys = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (Key))*myKeys.Length)
        };

        IntPtr c = new IntPtr(keyHolder.keys.ToInt32());

        for (int i = 0; i < myKeys.Length; i++)
        {
            Marshal.StructureToPtr(myKeys[i], c, false);
            c = new IntPtr(c.ToInt32() + Marshal.SizeOf(typeof(Key)));
        }

        Marshal.StructureToPtr(c, keyHolder.keys, false);

        IntPtr handle = IntPtr.Zero;

        var ret = createKeyChain(111, new []{keyHolder}, ref handle);

除了重点对象,这已损坏里面的内部串一切运作良好。 我怀疑这是破坏它的StructureToPtr。 我怎样才能让在C ++侧串秀?

谢谢。

Answer 1:

未做更改非托管代码,你别无选择,只能编组这一切你自己。 这看起来是这样的:

[StructLayout(LayoutKind.Sequential)]
public struct _Key
{
    public IntPtr keyName;
    public uint keySize;
}

[StructLayout(LayoutKind.Sequential)]
public struct _KeyHolder
{
    public string name;
    public uint numKeys;
    public IntPtr keys;
}

public struct Key
{
    public string keyName;
    public uint keySize;
}

public static _KeyHolder CreateKeyHolder(string name, Key[] keys)
{
    _KeyHolder result;
    result.name = name;
    result.numKeys = (uint)keys.Length;
    result.keys = Marshal.AllocHGlobal(keys.Length * Marshal.SizeOf(typeof(_Key)));
    IntPtr ptr = result.keys;
    for (int i = 0; i < result.numKeys; i++)
    {
        _Key key;
        key.keyName = Marshal.StringToHGlobalAnsi(keys[i].keyName);
        key.keySize = keys[i].keySize;
        Marshal.StructureToPtr(key, ptr, false);
        ptr += Marshal.SizeOf(typeof(_Key));
    }
    return result;
}

public static void DestroyKeyHolder(_KeyHolder keyHolder)
{
    IntPtr ptr = keyHolder.keys;
    for (int i = 0; i < keyHolder.numKeys; i++)
    {
        _Key key = (_Key)Marshal.PtrToStructure(ptr, typeof(_Key));
        Marshal.FreeHGlobal(key.keyName);
        ptr += Marshal.SizeOf(typeof(_Key));
    }
    Marshal.FreeHGlobal(keyHolder.keys);
}


Answer 2:

你仍然需要告诉.NET当元帅的字符串作为PChars中:

[StructLayout(LayoutKind.Sequential)]
public struct Key
{
      [MarshalAs(UnmanagedType.LPStr)]
      public string key;
      public uint size;
}

[StructLayout(LayoutKind.Sequential)]
public struct KeyHolder
{
      [MarshalAs(UnmanagedType.LPStr)]
      public string name;
      public uint keyCount;

      public Key[] keys;
}


文章来源: Marshaling nested structures from C# to C++