外部访问修饰符不起作用。

4

我尝试隐藏我的P/Invoke函数,比如这个:

[<DllImport("kernel32.dll", SetLastError=true)>]
extern bool private CreateTimerQueueTimer(IntPtr& phNewTimer, nativeint TimerQueue, WaitOrTimerDelegate Callback, nativeint Parameter, uint32 DueTime, uint32 Period, ExecuteFlags Flags)

奇怪的是,private 却被忽略了——这真的很烦人,因为我想隐藏与这些函数相关的所有笨重结构体和枚举。

我想我可以把所有东西都放在一个私有模块中,所以这并不是太大的问题,但我错过了什么吗?


1
闻起来像是一个 bug;把它们放在私有模块中确实听起来是最好的解决方法。 - Brian
3
这段话的意思是:就事论事而言,这听起来是利用接口文件的一个很好的应用案例(换句话说,使用*.fsi文件来隐藏某些元素)。我的翻译如下:就此而言,这似乎是使用接口文件的一个很好例子(也就是使用*.fsi文件来隐藏某些元素)。 - pblasucci
你的 extern 函数现在在什么上下文中?在类内还是? - Anders Gustafsson
@pblasucci,请注意,这不是一个“用例”。他们并没有为了让另一个功能有意义而在某些情况下破坏了访问修饰符关键字。请原谅我的语气,但当人们拒绝接受他们最喜爱的语言存在问题时,我无法忍受。对于语言的未来来说,这是不利的。 - Rei Miyasaka
@Brian 你们有公共的错误跟踪器吗?还是fsbugs@microsoft.com可以吗? - Rei Miyasaka
2
@ReiMiyasaka:哇!冷静点。我并没有说这是或不是一个错误。我没有权利做出这个判断。我只是提出了解决您问题的一种方法。这不是StackOverflow的目的吗? - pblasucci
1个回答

0

这将完成工作。

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 *) )

注意:

  • private 类只能从封闭模块中访问,这就是你需要的,所以只需将方法包装在 NativeMethods 类中;
  • 您不能将您的 extern 方法设置为 private,因为它将无法从模块 a 的其余部分访问;
  • 类的 extern 成员始终是 private,因此有另一个具有相同签名的方法;
  • 最后,使用 EntryPoint 解析命名。

我只是将extern调用放在一个私有嵌套模块中,并将包装函数放在持有它的公共模块中。 - Rei Miyasaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接