问题
I'm trying to hide my P/Invoke functions, like this one:
[<DllImport("kernel32.dll", SetLastError=true)>]
extern bool private CreateTimerQueueTimer(IntPtr& phNewTimer, nativeint TimerQueue, WaitOrTimerDelegate Callback, nativeint Parameter, uint32 DueTime, uint32 Period, ExecuteFlags Flags)
Strangely, though, the private
gets ignored -- which is really annoying, because I want to hide all the unwieldy structs and enums associated with these functions.
I guess I could put everything in a private module, so it's not too big of a deal, but am I missing something?
回答1:
This will do the job.
module a =
[<AbstractClass>]
type private NativeMethods() =
[<DllImport("kernel32.dll", EntryPoint="CreateTimerQueueTimer",
SetLastError=true)>]
static extern bool sCreateTimerQueueTimer( (* whatever *) )
static member CreateTimerQueueTimer = sCreateTimerQueueTimer
let usedInside = NativeMethods.CreateTimerQueueTimer
module b =
open a
// the next line fails to compile
let usedOutside = NativeMethods.CreateTimerQueueTimer( (* whatever *) )
Notes:
- private class can be accessed only from the enclosing module, this is what you need, so just wrap the methods in a
NativeMethods
class; - You cannot set your extern method private since it wouldn't be accessible from the rest of module
a
; - extern member of a class is always private, so there's another method with same signature;
- Finally, use
EntryPoint
to resolve naming.
来源:https://stackoverflow.com/questions/11216552/extern-access-modifiers-dont-work