Маршалинг неуправляемой структуры, содержащей элемент char * - PullRequest
0 голосов
/ 30 марта 2012

Я работаю с функцией обратного вызова, переходя от неуправляемого кода к моему управляемому коду C #.Обратный вызов имеет параметр void* eventData.EventData может быть нескольких различных типов структур.В моем коде C # я определяю eventData как IntPtr и использую Marshal.PtrToStructure, чтобы получить структуру.Для большинства структур у меня нет проблем.Однако я сталкиваюсь с проблемами, приводящими к маршалингу этого:

//! Structure for dose parameters

typedef struct
{
    //! the dose in µGrays
    float dose;

    unsigned short nbParameters;
    //! the corresponding parameters specified in the .ini file
    struct Parameters
    {
        //! parameter text
        const char* text;
        //! parameter value
        float value;
    } * parameters;

} DoseParameters;

Вот мое определение C # для структуры:

/// <summary>
/// Structure for dose parameters
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct DoseParameters {
    //! the dose in µGrays
    public float dose;

    public ushort nbParameters;
    //! the corresponding parameters specified in the .ini file

    [StructLayout(LayoutKind.Sequential)]
    public struct Parameters{
        //! parameter text        
        public string text;
        //! parameter value        
        public float value;
    }

    [MarshalAs(UnmanagedType.ByValArray)]
    public Parameters[] parameters;
}

Значения дозы и nbParameters преобразованы правильно.Это массив параметров, с которым я борюсь.Длина всегда одна, и для этого одного экземпляра Parameters.text ничего не понимает, а Parameters.value намного больше, чем должно быть.

Кажется, это как-то связано с символом * неопределенной длины.Хотя я новичок в материалах StructLayout / MarshalAs, поэтому не слишком уверен во всем этом.Я играл с различными комбинациями MarshalAs, LayoutKind.Explicit и FieldOffset, но безуспешно (очевидно).Я провел некоторые поиски и не нашел ничего похожего на мою ситуацию.

Ответы [ 2 ]

0 голосов
/ 31 марта 2012

Исправлено это путем изменения члена DoseParamters.parameters на IntPtr и использования ответа JaredPar на это: /135358/marshal-c-massiv-struktur-v-c

0 голосов
/ 30 марта 2012

Я считаю, что есть атрибут длины, который вы можете указать для типа символа * в C #, чтобы он хорошо конвертировался.

На самом деле есть инструмент конвертации, P / Invoke Interop Assistant, который вы, возможно, захотите проверить (упомянут в [1]). Он генерирует код C # из кода C для взаимодействия. Я использовал его один раз для проекта, и он работает довольно хорошо.

[1] http://msdn.microsoft.com/en-us/magazine/cc164193.aspx

РЕДАКТИРОВАТЬ: добавлено название инструмента

РЕДАКТИРОВАТЬ: http://social.msdn.microsoft.com/Forums/en-us/clr/thread/86412199-da26-4fe4-9450-351f8f3a74b8 аналогично?

...