Port C Struct to C # - PullRequest
       14

Port C Struct to C #

0 голосов
/ 26 апреля 2019

Из кода 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 Ответ

1 голос
/ 26 апреля 2019

Не зная более подробной информации о вашей конкретной стратегии взаимодействия, трудно быть точным, но это типичный пример маршалинга указателя на функцию.

  // 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...