I seem to run into all the weird problems. Anyway, I'll cut to the chase. Here's the C struct that the function is supposed to return:
struct AVS_Value {
short type; // 'a'rray, 'c'lip, 'b'ool, 'i'nt, 'f'loat, 's'tring, 'v'oid, or 'l'ong
// for some function e'rror
short array_size;
union {
void * clip; // do not use directly, use avs_take_clip
char boolean;
int integer;
float floating_pt;
const char * string;
const AVS_Value * array;
} d;
};
And here's the signature of the function that returns it:
AVSC_API(AVS_Value) avs_invoke(AVS_ScriptEnvironment *, const char * name, AVS_Value args, const char** arg_names);
AVSC_API basically just says that the function using the stdcall convention and that it's a dllexport function. Here's my C# translation of the C struct:
[StructLayout(LayoutKind.Explicit)]
public struct SValue {
[FieldOffset(0)] public char Type;
[FieldOffset(2)] public short ArrayLength;
[FieldOffset(4)] public IntPtr Data;
[FieldOffset(4)] public int Integer;
[FieldOffset(4)] public float Float;
}
When the pointer is used I do all the translations manually, since you can't have a string in the same place as a value type. Anyway, that works fine. Finally, here's the imported DLL function:
[DllImport("avisynth.dll", EntryPoint = "avs_invoke", CallingConvention = CallingConvention.StdCall)]
public static extern SValue _Invoke(IntPtr env, [MarshalAs(UnmanagedType.LPStr)] string name, SValue args, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] argNames);
The problem is, calling this function in my program makes the application crash. (No exception, it just crashes. "AppName.exe has encountered a problem and needs to close... yada yada yada.") But, I can make it work if I have the imported function return a ulong (which is an 8-byte value type, just like my struct) instead of an SValue, like so:
[DllImport("avisynth.dll", EntryPoint = "avs_invoke", CallingConvention = CallingConvention.StdCall)]
public static extern ulong _Invoke(IntPtr env, [MarshalAs(UnmanagedType.LPStr)] string name, SValue args, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] argNames);
When I do this, the function call executes just fine and it behaves just the way it's supposed to. I can cast the returned ulong to an SVideo and it works fine. But... why is there a problem returning a struct from the function?