Я работаю с неуправляемой библиотекой через P/Invoke, и она использует три структуры (хотя все они имеют одинаковый базовый макет, поэтому я опубликую только одну):
struct Agraph_t {
int tag:4;
int kind:4;
int handle:24;
char **attr;
char *didset;
char *name;
Agdata_t *univ;
Dict_t *nodes, *inedges, *outedges;
Agraph_t *root;
Agnode_t *meta_node;
Agproto_t *proto;
Agraphinfo_t u;
};
Из-за того, как моя оболочка использует эти объекты, мне приходится обращаться к структурам внутри Agraph_t
как к IntPtr
s. Я добавил свойства, упрощающие доступ к значениям битовых полей.
public struct Agraph_t {
public uint tag_kind_handle;
public IntPtr attr;
public string didset;
public string name;
public IntPtr univ;
public IntPtr nodes, inedges, outedges;
public IntPtr root;
public IntPtr meta_node;
public IntPtr proto;
public IntPtr u;
public uint Tag {
get { return (tag_kind_handle & 15u); }
}
public uint Kind {
get { return (tag_kind_handle & 240u) / 16; }
}
public uint Handle {
get { return (tag_kind_handle & 4294967040u) / 256; }
}
}
Прежде чем что-либо делать, я должен инициализировать неуправляемую библиотеку, задав ей размер каждой из трех структур.
aginitlib(Marshal.SizeOf(typeof(Agraph_t)), ..., ...);
Я не получаю ошибки при этом, и я могу нормально пользоваться библиотекой. Однако часть библиотеки делает собственный вызов aginitlib (у меня нет контроля над этим), используя размер неуправляемых структур. В этот момент библиотека предупреждает меня, что она была инициализирована с двумя разными размерами, что делает ее нестабильной (бросание AccessViolationException
после определенных операций).
Учитываются ли добавленные свойства в размере структуры и делают ли ее больше, чем неуправляемая версия? Я бы удалил их и посмотрел, что произойдет, но мой код сильно зависит от них, что усложняет задачу.
Нужно ли использовать StructLayoutAttribute
со свойством Size
? Единственное, что меня смущает, это IntPtr
s. Библиотека строго 32-битная, поэтому могу ли я смело предположить, что эти поля всегда будут 32-битными?