端口 C 结构到 C#

Port C Struct to C#

从 C 代码来看,这是另一个结构的一部分的结构:

struct loop_funcs {
  size_t (*loop_convert) (iconv_t icd,
                          const char* * inbuf, size_t *inbytesleft,
                          char* * outbuf, size_t *outbytesleft);
  size_t (*loop_reset) (iconv_t icd,
                        char* * outbuf, size_t *outbytesleft);
};

到目前为止,我已经在 C# 中定义了这个来使用这个结构:

        [StructLayout(LayoutKind.Sequential)]
        struct loop_funcs {
            ulong (loop_convert) (conv_struct icd,
                          string * inbuf, ulong inbytesleft,
                          string * outbuf, ulong outbytesleft)
            ulong (loop_reset) (conv_struct icd,
                       char* * outbuf, ulong outbytesleft)
        }

但是我不知道如何处理这种转换,它不是我目前在其他示例中找到的简单结构定义。

在不了解有关特定互操作策略的更多详细信息的情况下,很难做到准确,但这是函数指针封送处理的常见示例。

  // need a static class to contain the definitions of the managed
  // equivalent of function pointers, which are delegates
  static class Native
  {
    // assuming you are using these as callbacks, the Marshaler needs to know
    // how to fix up the call stack
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate ulong LoopConvertFunc([MarshalAs(UnmanagedType.Struct)]conv_struct icd,
                                          ref StringBuilder inbuf,
                                          ref ulong inbytesLeft,
                                          ref StringBuilder outbuf,
                                          ref ulong outbytesLeft);

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate ulong LoopResetFunc([MarshalAs(UnmanagedType.Struct)]conv_struct icd, ref StringBuilder outbuf, ref ulong outbytesLeft);
  }

  [StructLayout(LayoutKind.Sequential)]
  struct loop_funcs
  {
    Native.LoopConvertFunc loop_convert;
    Native.LoopResetFunc loop_reset;
  }

函数指针必须定义为委托,封送拆收器必须知道如何修复调用堆栈,因此您使用 UnmanagedFunctionPointer 属性。

此外,根据实际用例,StringBuilder 通常用于编组可写字符串缓冲区,使用 ref 关键字。