Explain type matrix
From what I can tell, there isn't a description of how to map unions to .NET types. This is a problem for me since I have an API that uses unions and I'd like to bind it using this library. It would also be nice if there was something like a reference sheet that described both simple and complex types in C mapped to the associated simple and complex types in .NET. According to this SO question, the StructLayout attribute combined with the FieldOffset can simulate this with structs, but I don't know how well this would map across the FFI boundary. The library I'm binding has the following structs and associated union:
struct syz_AutomationPoint {
int interpolation_type;
double values[6];
unsigned long long flags;
};
struct syz_AutomationAppendPropertyCommand {
int property;
struct syz_AutomationPoint point;
};
struct syz_AutomationClearPropertyCommand {
int property;
};
struct syz_AutomationSendUserEventCommand {
unsigned long long param;
};
union syz_AutomationCommandParams {
struct syz_AutomationAppendPropertyCommand append_to_property;
struct syz_AutomationClearPropertyCommand clear_property;
struct syz_AutomationSendUserEventCommand send_user_event;
};
struct syz_AutomationCommand {
syz_Handle target;
double time;
int type;
unsigned int flags;
union syz_AutomationCommandParams params;
};
SYZ_CAPI syz_ErrorCode syz_createAutomationBatch(syz_Handle *out, syz_Handle context, void *userdata,
syz_UserdataFreeCallback *userdata_free_callback);
SYZ_CAPI syz_ErrorCode syz_automationBatchAddCommands(syz_Handle batch, unsigned long long commands_len,
const struct syz_AutomationCommand *commands);
SYZ_CAPI syz_ErrorCode syz_automationBatchExecute(syz_Handle batch);
Therefore, one possible implementation of this translation might be:
using System.Runtime.InteropServices;
// ...
public struct AutomationPoint {
public int InterpolationType;
public double[6] Values;
public ulong Flags;
}
public struct AutomationAppendPropertyCommand {
public nint Property;
public AutomationPoint Point;
}
public struct AutomationClearPropertyCommand {
public int Property;
}
public struct AutomationSendUserEventCommand {
public uint param;
}
[StructLayout(LayoutKind.Explicit, Pack=1)]
public struct AutomationCommandParams {
[FieldOffset(0)]
public AutomationAppendPropertyCommand AppendToProperty;
[FieldOffset(56)]
public AutomationClearPropertyCommand ClearProperty;
// ...
}
The only major problem with this is that its majorly error-prone. I could use the sizeof operator but I'm not quite sure how I'd use that since FieldOffset requires a contiguous range. Is there a much better way of doing this?
Using FieldOffset and an explicit struct layout is the way to go when dealing with unions, I'm afraid - this is one of those parts that gets hairy quick.
@Nihlus Is there an easier way of computing the offsets, then? I really don't want to do [FieldOffset(sizeof(a) + sizeof(b) + sizeof(c) +...)]. That just looks really ugly.
That's the only way I'm aware of, unfortunately. Interop code is ugly by its nature.