I'm working with some F# code that uses platform invoke. One of the APIs I'm using returns a handle. Instead of using a nativeint
, I've implemented my own SafeHandle (specifically SafeHandleMinusOneIsInvalid
.) This makes working with the module containing the pinvoke signature a little clunky. Here is an example:
type MySafeHandle() =
inherit SafeHandleZeroOrMinusOneIsInvalid(true)
override this.ReleaseHandle() =
NativeMethods.FreeHandle(base.handle)
true
module NativeMethods =
[<DllImport("mylibrary.dll")>]
extern void GetHandle([<Out>]MySafeHandle& handle)
[<DllImport("mylibrary.dll")>]
extern void FreeHandle(nativeint handle)
This won't compile because the module and the class recursively reference each other, which doesn't work. If I move the module above MySafeHandle
, then GetHandle
won't see the SafeHandle.
I can't move the platform invoke methods inside of MySafeHandle
since it appears that extern methods in F# must be in modules (even though the compiler won't stop you from trying to put them in a class).
It also appears that F#'s recursive types don't work between a module and a class, just classes.
Is there a solution to this problem that does not require declaring two different modules? Ideally I'd like to keep all of my platform invoke code organized into one module.