Как я могу игнорировать поле при маршалинге структуры с помощью P / Invoke - PullRequest
11 голосов
/ 10 ноября 2009

Я хочу упорядочить структуру для использования с P / Invoke, но эта структура содержит поле, относящееся только к моему управляемому коду, поэтому я не хочу, чтобы оно было упорядочено, поскольку оно не принадлежит нативному состав. Это вообще возможно? Я искал атрибут, похожий на NonSerialized для сериализации, но он, кажется, не существует ...

struct MyStructure
{
    int foo;
    int bar;

    [NotMarshaled] // This attribute doesn't exist, but that's the kind of thing I'm looking for...
    int ignored;
}

Любое предложение будет оценено

Ответы [ 3 ]

6 голосов
/ 11 ноября 2009

Нет способа заставить CLR игнорировать поле. Вместо этого я бы использовал две структуры и, возможно, сделал бы одну членом другой.

struct MyNativeStructure 
{ 
    public int foo; 
    public int bar; 
} 

struct MyStructure 
{ 
    public MyNativeStruct native; 
    public int ignored; 
} 
1 голос
/ 22 января 2010

Два метода:

  1. Используйте класс вместо struct: структуры всегда передаются по указателю на API Windows или другие собственные функции. Замена звонка на doThis(ref myStruct) звонком на doThis([In, Out] myClass) должна помочь. После того, как вы это сделаете, вы можете просто получить доступ к полям, которые нельзя маршалировать, с помощью методов.

  2. Как я уже говорил, структуры (почти) всегда передаются по ссылке: следовательно, вызываемый объект ничего не знает о размерах структуры: как насчет того, чтобы оставить ваши дополнительные поля последними? При вызове нативной функции, которая нуждается в указателе вашей структуры и размере структуры, просто верите о ее размере, давая тот, который был бы без дополнительных полей. Я не знаю, является ли это законным способом упорядочить такую ​​структуру обратно при получении ее из нативной функции. Дополнительный вопрос: поля класса Маршаллера обрабатывают как частные? (Надеюсь нет ...)

0 голосов
/ 08 мая 2019

на основе моих тестов, свойство auto вроде:

private int marshaled { get; set; }

будет занимать пространство при маршалинге (Marshal.SizeOf)

Но! явно указанное свойство не будет:

private int skipped
{
    get { return 0; }
    set { }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...