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

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

struct MyStructure
{
    int foo;
    int bar;

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

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

Ответ 1

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

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

struct MyStructure 
{ 
    public MyNativeStruct native; 
    public int ignored; 
} 

Ответ 2

Два метода:

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

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

Ответ 3

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

private int marshaled { get; set; }

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

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

private int skipped
{
    get { return 0; }
    set { }
}