2014-01-10 85 views
1

我的類型提供程序使用一些本機x64庫。我使用 anyCpu x64標誌編譯了我的類型提供程序庫。在Visual Studio中使用x64庫的F#類型提供程序

現在,當我嘗試從Visual Studio中的另一個項目的IntelliSense加載我喜歡的類型提供給了我以下錯誤:

The type provider '...my type provider...' reported an error: An attempt was made to load a program with an incorrect format (Exception from HRESULT: 0x8007000B

只是要清楚,我得到這個錯誤不運行任何代碼,只需通過在Visual Studio中註冊類型提供程序。

當我嘗試從32位fsi加載它時,我得到相同的錯誤。但是,當我嘗試fsianycpu或64位fsi它工作正常。我在fsi中獲得我的類型和自動完成。

我猜這是因爲VS自己是x86,IntelliSense /靜態代碼分析也是x86,在某些時候他們嘗試加載依賴x86 lib和錯誤彈出的類型提供程序代碼。

不幸的是,庫只支持x64。

有沒有什麼辦法讓這項工作一起工作?

+1

如果您的提供者使用本機64位庫,那麼它不應該被編譯爲AnyCPU。不是。當然,它不能在32位機器上運行(或者像Visual Studio一樣在32位程序中運行)。 –

+0

你是對的,它應該被認爲是64位。 – Klark

回答

4

如果您的提供者使用本機64位庫,那麼它不應該編譯爲AnyCPU(除非您可以提供32位回退)。當然,它不能在32位機器上運行(或者像Visual Studio一樣在32位程序中運行)。

一個可能的解決方法用於在32位進程中調用代碼時提供回退託管方法(甚至是空存根)。例如:

static class NativeInterop { 
    [DllImport("My64BitLibrary.dll", EntryPoint = "DoStuff")] 
    private static int DoStuff64(int value); 

    public static int DoStuff(int value) { 
     if (Environment.Is64BitProcess) 
      return DoStuff64(value); 

     // This is a 32 bit process, I just return a dummy value 
     // for Visual Studio integration (if applicable) 
     return 0; 
    } 
} 

您的代碼不會直接調用進口DoStuff()功能,而是會打電話給託管的包裝,將呼叫重定向到本地功能的64個程序,它會執行別的 32位環境。你可能需要(這是一個未經測試的解決方案)添加第二級間接尋址,如果在JIT編譯此方法時(而不是在實際調用時)將加載依賴關係。

我想這不能應用到處,它取決於你在哪裏調用64位代碼,如果你可以提供一個工作存根。如果你不能滿足這個條件,那麼你就沒有機會把一個64位的庫(編譯成AnyCPU並不重要)整合到一個32位的進程中。

替代方法(如果你不能設法提供C#實現或一些假的)的32個進程可能對您的平臺相關的代碼轉移到外部服務(例如WCF service used for IPC)。該進程將始終爲64位,但是您的類型提供程序(因爲它不會對本機庫有任何直接依賴關係)可以編譯爲AnyCPU,並且它可以在32位進程內正常運行。你要付出的代價是IPC,而且是複雜性的一大增量。

+0

這個庫非常複雜,我沒有源代碼,所以將我的32位邏輯燒入它是不可能的。我希望得到一些F# - VS解決方案,比如爲F#64bit編譯intellisense,或者將庫編譯爲單獨的可執行文件,直接從類型提供程序調用並解析輸出/進行一些進程間通信等。 – Klark

+0

@Klark它是可行的,但它是可行的痛苦!您應該安裝(例如)一個WCF服務,並從您連接到該服務器的類型提供程序中進行安裝。然後XY位無關緊要,EXE託管的WCF服務將運行64位,並且您的類型提供程序(編譯爲AnyCPU)將在32位進程上運行。可能但表現不會那麼好 –

相關問題