2014-01-10 58 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位进程上运行。可能但表现不会那么好 –

相关问题