F#Type在Visual Studio中使用x64库的提供程序

时间:2014-01-10 12:25:14

标签: .net visual-studio f# x86-64 type-providers

我下面的类型提供程序使用一些本机x64库。我用 anyCpu x64标志编译了我的类型提供程序库。

现在,当我尝试从另一个项目加载我的类型提供程序时,Visual Studio中的IntelliSense会出现以下错误:

  

类型提供程序'...我的类型提供程序...'报告错误:An   尝试加载具有不正确格式的程序(例外   来自HRESULT:0x8007000B

为了说清楚,我在没有运行任何代码的情况下得到了这个错误,只需在visual studio中注册类型提供程序。

当我尝试从32位fsi加载它时,我得到了同样的错误。但是,当我尝试使用fsianycpu或64位fsi时,它可以正常工作。我在fsi中获得了我的类型和自动完成功能。

我想这是因为VS自己是x86,IntelliSense /静态代码分析也是x86,在某些时候他们尝试加载依赖于x86 lib的类型提供程序代码并弹出错误。

不幸的是,该库只支持x64。

有没有办法让这项工作在一起?

1 个答案:

答案 0 :(得分:4)

如果您的提供程序使用本机64位库,则不应将其编译为AnyCPU(除非您可以提供32位回退)。当然它不能在32位机器上运行(或在32位进程内作为Visual Studio运行)。

一个可能的解决方法是在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位进程中。

32位进程的替代方法(如果您无法管理提供C#实现或某些假实现)可能是将您的平台特定代码移动到外部服务(例如一个WCF service used for IPC)。该进程将始终为64位,但您的类型提供程序(因为它不会直接依赖于本机库)可以编译为AnyCPU,并且它将在32位进程内运行良好。您需要支付的价格是IPC,并且复杂性也会大幅增加。