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

Я хочу маршалировать структуру для использования с 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;
}

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


person Thomas Levesque    schedule 09.11.2009    source источник


Ответы (3)


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

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

struct MyStructure 
{ 
    public MyNativeStruct native; 
    public int ignored; 
} 
person Mattias S    schedule 11.11.2009
comment
Невозможно заставить CLR игнорировать поле: да, вы, вероятно, правы... Я подожду несколько дней, если у кого-то есть другая идея, но это, вероятно, лучший ответ, который я получу. Спасибо ! - person Thomas Levesque; 11.11.2009

Два метода:

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

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

person Giancarlo Todone    schedule 22.01.2010
comment
Частные поля также маршалируются - person Mathew Sachin; 22.02.2016

на основе моих тестов, автоматическое свойство, например:

private int marshaled { get; set; }

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

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

private int skipped
{
    get { return 0; }
    set { }
} 
person Vladislav Sorokin    schedule 08.05.2019
comment
Это потому, что ваше явное свойство не имеет резервного поля. Поля занимают место, методы и свойства — нет. Автосвойства имеют неявное резервное поле. - person Thomas Levesque; 11.05.2019
comment
@ThomasLevesque, ты абсолютно прав! так глупо, я забыл про фон автосвойств - person Vladislav Sorokin; 21.11.2020