Ни один из примеров, которые я видел до сих пор, не рассматривает проблему маршалинга структуры, содержащей объединение структур, содержащих рекурсивные ссылки. Я пытаюсь написать маршала для структуры, которая содержит их и до сих пор не удалось.F # P/Invoke Marshaling Рекурсивные структуры
Например:
typedef enum {
My_StructA = 0x7878,
My_StructB
} MyStructTag;
typedef struct _MyStruct MyStruct;
struct _MyStruct {
MyStructTag discriminator;
union {
struct {
int a;
int b;
} StructA;
struct {
int c;
MyStruct* d;
} StructB;
} MyUnion;
};
Я попытался определить структуры следующим образом:
type MyStructTag =
| My_StructA = 0x7878
| My_StructB = 0x7879
[<Struct; StructLayout(LayoutKind.Sequential)>]
type StructA =
val mutable a : int
val mutable b : int
[<Struct; StructLayout(LayoutKind.Sequential)>]
type StructB =
val mutable c : int
val mutable d : MyStruct
[<Struct; StructLayout(LayoutKind.Explicit)>]
type MyStruct =
[<FieldOffset(0)>] val discriminator : MyStructTag
[<FieldOffset(4)>] val structA : StructA
[<FieldOffset(4)>] val structB : StructB
Обратите внимание, что причина, я потрудился определить MyStruct явно должен позволить себе использовать маршала. OffsetOf() и Marshal.SizeOf() при написании пользовательского маршалера для этой структуры. Из того, что я видел, писать собственный маршалер - единственный способ справиться с профсоюзами. Если я ошибаюсь, ссылки будут очень признательны!
Ошибки я получаю при написании выше кода:
error FS0039: The type 'MyStruct' is not defined
Я предполагаю, что это потому, что только различали тип союзов можно определить рекурсивно. Однако я не знаю другого способа представления этих структур в F #.
Заранее благодарю вас за ваше время.
спасибо! Так оно и было. Один вопрос: я никогда не видел конструкцию nativeptr <| insert unmanaged type here |>. У MSDN нет хорошего объяснения, и google-коды не дали никаких просветительских фрагментов. – arachnid
@arachnid - 'nativeptr <'t>' - F # -специальный тип для работы с указателями. На самом деле это просто псевдоним для 'System.IntPtr', но модуль' NativeInterop.NativePtr' предоставляет несколько полезных функций для взаимодействия с этими указателями строго типизированным способом. – kvb