From what I have learned, to use P/Invoke in F#, the function signature has to be declared first using DllImport like this:
[<DllImport("kernel32.dll", EntryPoint="CopyFile")>]
extern bool copyfile(char[] lpExistingFile, char[] lpNewFile, bool bFailIfExists);
That's all good when the DLL name is known at compile time. How do I interface with an unmanaged C/C++ DLL if I can only discover the name at runtime?
Alternatively, you can come up with a solution that generates PInvoke methods dynamically.
open System
open System.Reflection
open System.Reflection.Emit
open System.Runtime.InteropServices
let assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("PInvokeLibrary"), AssemblyBuilderAccess.Run)
let module_builder = assembly.DefineDynamicModule ("PInvokeLibrary")
let define_dynamic_pinvoke<'d when 'd :> Delegate> (name, library) =
let invoke = typeof<'d>.GetMethod ("Invoke") (* signature of delegate 'd *)
let parameters =
invoke.GetParameters ()
|> Array.map (fun p -> p.ParameterType)
let type_builder = module_builder.DefineType (name, TypeAttributes.Public)
let method_builder =
type_builder.DefinePInvokeMethod (
name,
library,
MethodAttributes.Public ||| MethodAttributes.Static ||| MethodAttributes.PinvokeImpl,
CallingConventions.Standard,
invoke.ReturnType,
parameters,
CallingConvention.Winapi,
CharSet.Ansi)
method_builder.SetImplementationFlags (method_builder.GetMethodImplementationFlags () ||| MethodImplAttributes.PreserveSig)
let result_type = type_builder.CreateType ()
let pinvoke = result_type.GetMethod (name)
Delegate.CreateDelegate (typeof<'d>, pinvoke) :?> 'd
let beep = define_dynamic_pinvoke<Func<int, int, bool>> ("Beep", "kernel32.dll")
beep.Invoke (800, 100)
The native APIs for this are LoadLibrary() and GetProcAddress(). Not sure if there are managed versions of that, but a Google search found something interesting:
Type-safe Managed wrappers for kernel32!GetProcAddress.
Opening line of that is:
Pinvoke is cool in managed code, but sometimes you need to get straight at kernel32!GetProcAddress. For example, maybe you need dynamic control over which unmanaged dll you want to load.
Sounds like what you want to do, no? Rest of the article here.
This problem is not specific to F#. You would need to build a proxy DLL in C++/CLI which will be responsible for loading necessary dll using LoadLibrary function from win API.
I guess it would be better if you could pass the signature of a native F# function to define_dynamic_pinvoke, like define_dynamic_pinvoke<(int * int -> bool)> ("Beep", "kernel32.dll"), but I admit I don't know how to achieve that.
You can rewrite the sample as:
let beep = define_dynamic_pinvoke<delegate of (int * int) -> bool> ("Beep", "kernel32.dll")
Related
After I build the library below and then link a program with it, the functions libInit, driveList, and freeSpace are visible to the program that linked to the library, which is what I expect.
I do not know how to reference the enums contained in the library. Are the enums visible or can they be made visible to the linked program, and, if so, how are they referenced?
namespace Toa.volLib
open System
open System.Threading
open System.Collections.Generic
open System.Text
open System.IO
open Microsoft.Win32
[<AutoOpen>]
module volLib =
type volTypes = GB = 1000000000L | Min_c = 5000000000L | Min_d = 10000000000L
let libInit = ref false
let driveList () =
DriveInfo.GetDrives()
let freeSpace drive =
let di = DriveInfo(drive)
di.AvailableFreeSpace
If libInit and the other functions from the module are visible, it means you have linked your library correctly.
If you try to access the enum, you need to prefix it with the enum name, like:
let accessEnum = volTypes.GB
That is different than what you can do with F# discriminated union types. If you define a union like
type volUnion =
| GB2
| Min_c2
| Min_d2
then you can access each case just by its name, like:
let accessUnion = GB2
I'm trying to create a solution that has a lower-level library that will know that it needs to save and load data when certain commands are called, but the implementation of the save and load functions will be provided in a platform-specific project which references the lower-level library.
I have some models, such as:
type User = { UserID: UserID
Situations: SituationID list }
type Situation = { SituationID: SituationID }
And what I want to do is be able to define and call functions such as:
do saveUser ()
let user = loadUser (UserID 57)
Is there any way to define this cleanly in the functional idiom, preferably while avoiding mutable state (which shouldn't be necessary anyway)?
One way to do it might look something like this:
type IStorage = {
saveUser: User->unit;
loadUser: UserID->User }
module Storage =
// initialize save/load functions to "not yet implemented"
let mutable storage = {
saveUser = failwith "nyi";
loadUser = failwith "nyi" }
// ....elsewhere:
do Storage.storage = { a real implementation of IStorage }
do Storage.storage.saveUser ()
let user = Storage.storage.loadUser (UserID 57)
And there are variations on this, but all the ones I can think of involve some kind of uninitialized state. (In Xamarin, there's also DependencyService, but that is itself a dependency I would like to avoid.)
Is there any way to write code that calls a storage function, which hasn't been implemented yet, and then implement it, WITHOUT using mutable state?
(Note: this question is not about storage itself -- that's just the example I'm using. It's about how to inject functions without using unnecessary mutable state.)
Other answers here will perhaps educate you on how to implement the IO monad in F#, which is certainly an option. In F#, though, I'd often just compose functions with other functions. You don't have to define an 'interface' or any particular type in order to do this.
Develop your system from the Outside-In, and define your high-level functions by focusing on the behaviour they need to implement. Make them higher-order functions by passing in dependencies as arguments.
Need to query a data store? Pass in a loadUser argument. Need to save the user? Pass in a saveUser argument:
let myHighLevelFunction loadUser saveUser (userId) =
let user = loadUser (UserId userId)
match user with
| Some u ->
let u' = doSomethingInterestingWith u
saveUser u'
| None -> ()
The loadUser argument is inferred to be of type User -> User option, and saveUser as User -> unit, because doSomethingInterestingWith is a function of type User -> User.
You can now 'implement' loadUser and saveUser by writing functions that call into the lower-level library.
The typical reaction I get to this approach is: That'll require me to pass in too many arguments to my function!
Indeed, if that happens, consider if that isn't a smell that the function is attempting to do too much.
Since the Dependency Inversion Principle is mentioned in the title of this question, I'd like to point out that the SOLID principles work best if all of them are applied in concert. The Interface Segregation Principle says that interfaces should be as small as possible, and you don't get them smaller than when each 'interface' is a single function.
For a more detailed article describing this technique, you can read my Type-Driven Development article.
You can abstract storage behind interface IStorage. I think that was your intention.
type IStorage =
abstract member LoadUser : UserID -> User
abstract member SaveUser : User -> unit
module Storage =
let noStorage =
{ new IStorage with
member x.LoadUser _ -> failwith "not implemented"
member x.SaveUser _ -> failwith "not implemented"
}
In another part of your program you can have multiple storage implementations.
type MyStorage() =
interface IStorage with
member x.LoadUser uid -> ...
member x.SaveUser u -> ...
And after you have all your types defined you can decide which to use.
let storageSystem =
if today.IsShinyDay
then MyStorage() :> IStorage
else Storage.noStorage
let user = storageSystem.LoadUser userID
I have a situation where I need to downcast twice in one procedure using :?>. I have a custom EventArgs class (which inherits System.EventArgs), and an instance of an abstract class within that custom EventArgs. Upon receiving the event, I need to downcast twice. Once for the custom EventArgs, and once for the abstract class within that custom EventArgs. I have to do this potentially millions of times a day, so I'm wondering if there's anything inherently slow about downcasting.
For grins, I put together the following little function:
let castToStream (o:Object) = o :?> Stream
and called it with the following code:
[<EntryPoint>]
let main argv =
let stm1 = new FileStream("output.tmp", FileMode.Create, FileAccess.ReadWrite, FileShare.Read)
let obj = stm1 :> Object
let stm2 = castToStream obj
0 // return an integer exit code
When it is compiled, castToStream turns into this IL:
.method public static class [mscorlib]System.IO.Stream
castToStream(object o) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: unbox.any [mscorlib]System.IO.Stream
IL_0007: ret
} // end of method Program::castToStream
which in this case is effectively 1 real instruction, unbox.any. Unbox.any for a reference type is equivalent to a castclass instruction. From the description, you'll take a one-time initial hit to load the type if it's not already loaded, then it's going to be a whatever magic is necessary to determine if the types are equivalent (likely using Type.IsAssignableFrom(), but I don't know for sure). However, unless your class hierarchy is super deep (and it shouldn't be), I would expect this to take microseconds on a typical machine.
For the curious, I initially had the code for castToStream inline, but the f# compiler saw through my shenanigans and removed all the casting entirely.
I'm trying to compile the source code from : Custom WPF Controls in F#
How ever this line :
let (handler, event) = Event.create<EventArgs>()
raises an error :
The value, constructor, namespace or type 'create' is not defined
The MSDN's Control.Event Module (F#) page does speak about such a function :
The additional functionality provided by the Event module is
illustrated here. The following code example illustrates the basic use
of Event.create to create an event and a trigger method, add two
event handlers in the form of lambda expressions, and then trigger the
event to execute both lambda expressions.
type MyType() =
let myEvent = new Event<_>()
member this.AddHandlers() =
Event.add (fun string1 -> printfn "%s" string1) myEvent.Publish
Event.add (fun string1 -> printfn "Given a value: %s" string1) myEvent.Publish
member this.Trigger(message) =
myEvent.Trigger(message)
let myMyType = MyType()
myMyType.AddHandlers()
myMyType.Trigger("Event occurred.")
However note that it's only mentionned in the description, not in the example.
Also, the Control.Event Module (F#) page has no reference to such a create function.
I guess it might be an old function or something, but I'm new to F# so I can't see what it should be replaced with..
Event.create is a fairly old API for events, from before F# 2.0 judging by what's on MSDN. It gave you a trigger function and a published event - both of which now live as Publish and Trigger members of Event class.
So if you wanted to implement create in the 'modern' terms, it might look somewhat like this:
module Event =
let create<'T> () =
let event = Event<'T>()
event.Trigger, event.Publish
I don't suggest you use it universally, but perhaps that's good enough to bring that old code back to life (the correct approach here being refactoring it to use Publish and Trigger instead of create).
I have a non-disposable class with Open/Close syntax that I'd like to be able to use, so I'm trying to inherit from it, and work the Open into the new and the Close into Dispose.
The second part is ok, but I can't work out how to do the Open:
type DisposableOpenCloseClass(openargs) =
inherit OpenCloseClass()
//do this.Open(openargs) <-- compiler no like
interface IDisposable
with member this.Dispose() = this.Close()
(cf. this question which I asked a long time ago, but I can't join the dots to this one)
Key is as this:
type OpenCloseClass() =
member this.Open(x) = printfn "opened %d" x
member this.Close() = printfn "closed"
open System
type DisposableOpenCloseClass(openargs) as this =
inherit OpenCloseClass()
do this.Open(openargs)
interface IDisposable
with member this.Dispose() = this.Close()
let f() =
use docc = new DisposableOpenCloseClass(42)
printfn "inside"
f()
As Brian suggests, you can use the as this clause. However, in F#, it is usually recomended to use subclassing (inheritance) only when there is a really good reason for that (e.g. you need to implement some virtual class and pass it to a .NET library).
If I was implementing your example, I would probably prefer function returning IDisposable using a simple object expression:
let disposableOpenClose(openargs) =
let oc = new OpenCloseClass()
oc.Open(openargs)
{ new IDisposable with
member this.Dispose() = oc.Close() }
let f() =
use docc = disposableOpenClose(42)
printfn "inside"
To some point, this is just a personal preference, but I think it is a preferred option, because it is simpler than using inheritance (although I don't have any document to link here :-)). Also, the compiled code may be a bit simpler, because handling as this may require some runtime checks.