Как CLR выполняет маршалинг структуры, содержащей только одно поле, при вызове неуправляемого кода? - PullRequest
1 голос
/ 05 мая 2011

По умолчанию, как 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, якобы для достижения поведения, которое я спросите об этом выше.

Есть ли разница в случае, когда определено только одно поле? Или это просто делает поведение по умолчанию более явным?

1 Ответ

2 голосов
/ 05 мая 2011

Относительно вашего вопроса о неявном / явном:

Это приведет к точно так же. По умолчанию LayoutKind (для C #) является последовательным, а первый элемент в структуре с этим макетом - всегда со смещением 0 . (Позиции следующих элементов будут зависеть от выбранной упаковки, как описано во второй ссылке.)

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