端口C结构到C#

问题描述 投票:0回答:1

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

但是我对如何处理这种转换感到迷茫,这不是我在其他例子中到目前为止发现的简单结构定义。

c# c pinvoke
1个回答
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关键字编组可写字符串缓冲区。

© www.soinside.com 2019 - 2024. All rights reserved.