2012-06-26 88 views
4

我試圖隱藏我的P/Invoke功能,像這樣的:的extern訪問修飾符不工作

[<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文件來隱藏某些元素)。 – pblasucci

+0

現在在什麼情況下你的'extern'功能?在一堂課內,或? –

回答

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

注:

  • 私人類只能從封閉模塊進行訪問,這是你需要什麼,所以只是包裹在NativeMethods類的方法;
  • 你不能設置你的extern方法私人,因爲它不會從模塊的其餘部分a訪問;
  • extern一個類的成員總是私有的,所以有另一種方法具有相同的簽名;
  • 最後,使用EntryPoint來解析命名。
+0

我只是把外部調用放在一個私有嵌套模塊中,並且包裝函數在保存它的公共模塊中。 –