简体   繁体   English

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

[英]F# Type Provider that uses x64 libraries in Visual Studio

My type provider underneath uses some native x64 libraries. 我下面的类型提供程序使用一些本机x64库。 I compiled my type provider library with anyCpu x64 flag. 我用 anyCpu x64标志编译了类型提供程序库。

Now, when I try to load my type provider from another project IntelliSense in Visual Studio gives me following error: 现在,当我尝试从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 类型提供程序“ ...我的类型提供程序...”报告了一个错误:试图加载格式不正确的程序(HRESULT的异常:0x8007000B

Just to make it clear, I get this error without running any code, just by registering the type provider in visual studio. 为了清楚起见,仅通过在Visual Studio中注册类型提供程序,即可在不运行任何代码的情况下收到此错误。

When I try to load it from 32 bit fsi I get the same error. 当我尝试从32位fsi加载它时,我得到了相同的错误。 But when I try with fsianycpu or 64 bit fsi it works fine. 但是,当我尝试用fsianycpu或64位fsi它工作正常。 I get my types and auto-completion in fsi . 我在fsi得到了类型和自动完成功能。

I guess that this happens because VS it self is x86, IntelliSense/static code analysis are also x86, at some point they try to load type provider code that relies on x86 lib and errors pop up. 我猜想发生这种情况是因为VS本身就是x86,IntelliSense /静态代码分析也是x86,在某些时候,他们试图加载依赖x86 lib的类型提供程序代码,并弹出错误。

Unfortunately that library only supports x64. 不幸的是,该库仅支持x64。

Is there any way to make this work together? 有什么办法可以使它们一起工作?

If your provider uses native 64 bit libraries then it shouldn't be compiled as AnyCPU (unless you can provide a 32 bit fallback). 如果您的提供程序使用本机64位库,则不应将其编译为AnyCPU(除非您可以提供32位回退)。 Definitely it can't run on a 32 bit machine (or inside a 32 bit process as Visual Studio). 绝对不能在32位计算机上运行(或在Visual Studio的32位进程中运行)。

One possible workaround is to provide a fallback managed method (or even an empty stub) when your code is called within a 32 bit process. 一种可能的解决方法是在32位进程中调用代码时提供一个后备托管方法(甚至是空的存根)。 For example: 例如:

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;
    }
}

Your code won't call directly imported DoStuff() function, instead it'll call a managed wrapper that will redirect call to native function on 64 bit processes and it'll perform something else on 32 bit environment. 您的代码不会调用直接导入的DoStuff()函数,而是会调用托管包装器,该包装器将在64位进程上将调用重定向到本机函数,并且将在32位环境中执行其他操作。 You may need (this is an untested solution) to add a second level of indirection if dependencies will be loaded when JIT compiles this method (and not when effectively they're called). 如果在JIT编译此方法时(而不是在有效地调用它们时)将加载依赖项,则可能需要(这是一个未经测试的解决方案)添加第二个间接级别。

I suppose this can't be applied everywhere, it depends on where you call 64 bit code and if you can provide a working stub. 我想这不可能在所有地方都应用,这取决于您在哪里调用64位代码以及是否可以提供有效的存根。 If you can't satisfy this condition then you don't have chances to integrate a 64 bit library (it doesn't matter if compiled as AnyCPU) into a 32 bit process. 如果您不能满足此条件,则您将没有机会将64位库(如果编译为AnyCPU则无关紧要)集成到32位进程中。

An alternative approach (in case you can't manage to provide a C# implementation or some fake one) for 32 bit processes could be to move your platform specific code to an external service (for example a WCF service used for IPC ). 对于32位进程,一种替代方法 (以防您无法提供C#实现或某些伪造的实现)可能是将平台特定的代码移至外部服务(例如, 用于IPCWCF服务 )。 That process will always be 64 bit but your type provider (because it won't have any direct dependency to a native library) can be compiled as AnyCPU and it'll run fine inside a 32 bit process. 该进程将始终为64位,但是您的类型提供程序(因为它不会直接依赖于本机库)可以编译为AnyCPU,并且可以在32位进程中正常运行。 The price you'll pay is IPC and a big increment of complexity. 您要付出的代价是IPC和复杂性的大幅增加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM