По умолчанию, как CLR упорядочивает структуру, которая содержит только одно поле, но определяет несколько методов, свойств, операторов и т. Д. При вызове неуправляемой функции через P / Invoke?
Упрощенная версия рассматриваемой структуры может выглядеть примерно так:
public struct SimpleStruct
{
private IntPtr _value;
public SimpleStruct(IntPtr value)
{
this._value = value;
}
public int MyMethod()
{
return 42;
}
}
Определенная неуправляемая функция, вызываемая здесь, не имеет значения, поэтому для обсуждения просто предположим что-то простое из Windows API, например:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindow(SimpleStruct hWnd);
В частности, меня интересует, будет ли структура маршалироваться, как если бы это был тип IntPtr
, или CLR пытается маршалировать структуру, как если бы это была более сложная структура с несколькими полями. Я понимаю, что "под капотом" все примитивные типы (включая IntPtr
и Int32
) реализованы как структуры. Но я не уверен, существует ли какой-то специальный корпус, который обрабатывает эти «известные» структуры, представляющие примитивные типы, иначе, чем он бы обрабатывал пользовательские.
Я понимаю, что только поля внутри типа доступны, и любые методы, свойства или события недоступны из неуправляемого кода, и это именно то, что я хочу. Я бы хотел, чтобы приведенная выше структура маршалировалась в неуправляемую функцию точно так же, как если бы объявление было переписано для указания параметра типа IntPtr
:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindow(IntPtr hWnd);
Соответственно, изменяется ли поведение при добавлении следующих атрибутов в определение структуры?
[StructLayout(LayoutKind.Explicit)]
public struct OtherStruct
{
[FieldOffset(0)]
private IntPtr _value;
public SimpleStruct(IntPtr value)
{
this._value = value;
}
public int MyMethod()
{
return 42;
}
}
Я когда-либо использовал FieldOffsetAttribute
только при моделировании объединения (т. Е. Нескольких полей), но я видел, как это было сделано в некотором собственном коде Microsoft, якобы для достижения поведения, которое я спросите об этом выше.
Есть ли разница в случае, когда определено только одно поле? Или это просто делает поведение по умолчанию более явным?