I've boiled this down to a simple example. I am writing some interop code between C# and C, and I have the following very simple struct on the unmanaged side:
typedef struct {
bool create_if_missing;
fdb_custom_cmp_variable custom_cmp;
} fdb_kvs_config;
typedef int (*fdb_custom_cmp_variable)(void *a, size_t len_a,
void *b, size_t len_b);
So I've created this on the managed side:
public struct fdb_kvs_config
{
[MarshalAs(UnmanagedType.I1)]
public bool create_if_missing;
[MarshalAs(UnmanagedType.FunctionPtr)]
public IntPtr custom_cmp;
}
I want to use this unmanaged function
extern __declspec(dllexport)
fdb_kvs_config fdb_get_default_kvs_config(void);
And so I have this equivalent:
[DllImport("forestdb", CallingConvention=CallingConvention.Cdecl)]
public static extern fdb_kvs_config fdb_get_default_kvs_config();
However, this throws an exception:
An unhandled exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in ForestDB.Test.exe
Additional information: Method's type signature is not PInvoke compatible.
Note: I've tried various MarshalAs
combinations with no luck. Also note that I am only charged with the C# side of things, the C API is developed by someone else and I have no control over it.
If this simple signature is not P/Invoke compatible then what the heck is? For bonus points, why does it work on OS X in Mono?