I have a native C library and I want do some F# coding with it. The thing is I get exception:
System.TypeLoadException: Cannot marshal field 'log' of type 'LoggingModel': There is no marshaling support for this type.
at System.StubHelpers.ValueClassMarshaler.ConvertToNative(IntPtr dst, IntPtr src, IntPtr pMT, CleanupWorkList& pCleanupWorkList)
at FSI_0009.Initialize(ComponentOverrideFlags flags, LoggingModel& loggingModel, ThreadingModel& threadingModel, SchedulingModel& schedulingModel, IntPtr memoryModel)
at .$FSI_0011.main@() in D:\dev_p\f#\FunBindings\FunExample\Environment.fs:line 16 Stopped due to error
Here the code:
module Interop
[<CLSCompliant(true); Flags>]
type LogTarget =
| None = 0
| Console = 1
| Trace = 2
| Custom = 4
[<UnmanagedFunctionPointer(CallingConvention.Cdecl)>]
type LogCallback = delegate of LogTarget * string * string * nativeint -> unit
[<UnmanagedFunctionPointer(CallingConvention.Cdecl)>]
type ReleaseCallback = delegate of nativeint -> unit
[<Struct>]
type LoggingModel =
val mutable targets : LogTarget
val mutable log : LogCallback
val mutable deleteModel : ReleaseCallback
val mutable userparam : IntPtr
[<DllImport("CLIBRARY.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "txInitialize")>]
[<MethodImpl(MethodImplOptions.ForwardRef)>]
extern int Initialize(ComponentOverrideFlags flags, LoggingModel& loggingModel, ThreadingModel& threadingModel, SchedulingModel& schedulingModel, IntPtr memoryModel)
module Environment
let initialize =
let mutable loggingModel = new LoggingModel()
let mutable threadingModel = new ThreadingModel()
let mutable schedulingModel = new SchedulingModel()
Initialize(ComponentOverrideFlags.None, &loggingModel, &threadingModel, &schedulingModel, IntPtr.Zero)
Basically, I get the aforementioned error when I try to execute "initialize" function in interactive.
I would really appreciate any help.
Update: I've checked the code a bit more and noticed that outside of the interactive console it seems to be working, without failing with exceptions. I need to provide a bit more coverage for CLibrary to be sure. Meanwhile, if there anybody who knows what could cause this exception and how it could be prevented, I would really appreciate the answer.
I think the problem is that delegate of LogTarget * string * string * nativeint -> unit
declares a delegate where the arguments are curried. (This doesn't really make sense to me either since a * b
normally represents a tuple.)
The subtly different delegate of (LogTarget * string * string * nativeint) -> unit
declares a delegate with tupled arguments which would be compatible with a native function.
You can see this difference if you try and assign a .NET method to two different delegate types:
type Curried = delegate of int * int -> int
type Tupled = delegate of (int * int) -> int
//let a = new Curried (Math.Max) // doesn't compile
let b = new Tupled (Math.Max) // works
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With