2014-09-23 4 views
1

Я получаю обратные вызовы из C++ DLL и нужно принять на структуру вида:Вызов C++ DLL из C# с профсоюзами

typedef struct { 
    union { 
    SXAnyDevice any_device; 
    SXInternalDevice internal; 
    SXExternalDevice external; 
    } 
    int device_type; 
} SXDevice; 

я создал структур, на которые ссылаются в C# и установил явные но у меня есть проблема с установкой FieldOffset для поля device_type, поскольку ссылочные структуры в объединении не имеют одинакового размера.

[StructLayout(LayoutKind.Explicit, CharSet=CharSet.Ansi)] 
public struct SXDevice { 
    [FieldOffset(0)] 
    public SXAnyDevice any_device; 
    [FieldOffset(0)] 
    public SXInternalDevice internal_device; 
    [FieldOffset(0)] 
    public SXExternalDevice external_device; 
    [FieldOffset(**Not sure how to handle this**)] 
    public int device_type; 
} 

Любые идеи, как лучше всего это сделать?

ответ

1

Как быстро получить смещение: использовать значение, возвращаемое offsetof(SXDevice, device_type) в C++.

Объяснение для смещения:

союз занимает столько же места, как это самый большой компонент.

Пусть maxSize = max(sizeof(SXAnyDevice), sizeof(SXInternalDevice), sizeof(SXExternalDevice))

Теперь все зависит от того, как он настроен на С ++ стороны:

  • Если нет отступов (#pragma pack(1)), то смещение device_type будет просто равна maxSize
  • Если имеется прокладка, выровняйте maxSize до следующей границы упаковки

От #pragma pack docs:

Определяет значение, в байтах, который будет использоваться для упаковки. Если параметр компилятора/Zp не установлен для модуля, значение по умолчанию для n равно 8. Допустимые значения: 1, 2, 4, 8 и 16. Выравнивание элемента будет на границе, которая является либо множественной n или кратное размеру члена, в зависимости от того, что меньше.

+0

Блестящий, я отдам это. Есть ли способ включить что-то в определение структуры, а я не уверен, как лучше всего устанавливать смещения во время выполнения? –

+0

@David Извините, но я не понимаю, что вы имеете в виду ... –

+0

У меня есть fieldoffset как атрибут в структуре. Я не могу поместить sizeof (SXAnyDevice) в качестве параметра fieldoffset, поскольку компилятор жалуется, что атрибут атрибута должен быть константным выражением, выражением типа или выражением для создания массива. –