.net 在Visual Studio中使用x64库的F#类型提供程序

.net 在Visual Studio中使用x64库的F#类型提供程序,.net,visual-studio,f#,x86-64,type-providers,.net,Visual Studio,F#,X86 64,Type Providers,我下面的类型提供程序使用一些本机x64库。我用anyCpu x64标志编译了我的类型提供程序库 现在,当我尝试从Visual Studio中的另一个项目IntelliSense加载类型提供程序时,出现以下错误: 类型提供程序“…我的类型提供程序…”报告了一个错误:错误 试图加载格式不正确的程序(异常 来自HRESULT:0x8007000B 为了澄清这一点,我没有运行任何代码,只是在VisualStudio中注册了类型提供程序,就得到了这个错误 当我尝试从32位fsi加载它时,我得到了相同的错误

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

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

类型提供程序“…我的类型提供程序…”报告了一个错误:错误 试图加载格式不正确的程序(异常 来自HRESULT:0x8007000B

为了澄清这一点,我没有运行任何代码,只是在VisualStudio中注册了类型提供程序,就得到了这个错误

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

我猜这是因为VS it self是x86,IntelliSense/静态代码分析也是x86,在某个时候,他们试图加载依赖x86库的类型提供程序代码,并弹出错误

不幸的是,该库只支持x64


有什么方法可以让它一起工作吗?

如果您的提供程序使用本机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位进程,另一种方法是将特定于平台的代码移动到外部服务(例如a)。该进程将始终是64位的,但您的类型提供程序(因为它不会直接依赖于本机库)可以编译为AnyCPU,并且在32位进程内运行良好。您要付出的代价是IPC和复杂性的大幅增加。

如果您的提供商使用本机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位进程,另一种方法是将特定于平台的代码移动到外部服务(例如a)。该进程将始终是64位的,但您的类型提供程序(因为它不会直接依赖于本机库)可以编译为AnyCPU,并且在32位进程内运行良好。您要付出的代价是IPC和复杂性的大幅增加。

如果您的提供商使用本机64位库,则不应将其编译为AnyCPU。它不是。它肯定不能在32位机器上运行(或在32位进程内,如Visual Studio)。您是对的,应该将其视为64位。如果您的提供程序使用本机64位库,则不应将其编译为AnyCPU。事实并非如此。它肯定不能在32位计算机上运行(或在32位进程中运行,如Visual Studio).你是对的,它应该被认为是64位的。该库非常复杂,我没有源代码,因此不可能将我的32位逻辑烘焙到其中。我希望得到一些F#-VS解决方案,比如为F#64位创建intellisense,或者将库编译为单独的可执行文件,直接从类型提供程序调用它并解析输出/执行一些操作进程内通信等@Klark这是可行的,但很痛苦!您应该安装(例如)WCF服务,并从您的类型提供程序连接到该服务器。然后XY位无关紧要,EXE托管的WCF服务将运行64位,您的类型提供程序(编译为AnyCPU)将在32位进程上运行。可能,但性能不会太好库非常复杂,而且我没有源代码,因此不可能将32位逻辑烘焙到其中。我希望得到一些F#-VS解决方案,如为F#64位创建intellisense,或将库编译为单独的可执行文件,直接从类型提供程序调用并解析它输出/执行一些进程内通信等@Klark这是可行的,但很痛苦!您应该安装(例如)WCF服务,并从您的类型提供程序连接到该服务器。然后XY位无关紧要,EXE托管的WCF服务将运行64位,而您的