将C端口结构转换为C#

时间:2019-04-26 17:40:11

标签: c# c pinvoke

在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)
        }

但是,我对如何处理此转换一无所知,这不是到目前为止在其他示例中找到的简单结构定义。

1 个答案:

答案 0 :(得分:1)

在不了解有关您特定互操作策略的更多细节的情况下,很难精确指出,但这是函数指针封送处理的一个常见示例。

  // 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来封送可写字符串缓冲区。