简体   繁体   中英

F# Type Provider that uses x64 libraries in Visual Studio

My type provider underneath uses some native x64 libraries. I compiled my type provider library with anyCpu x64 flag.

Now, when I try to load my type provider from another project IntelliSense in Visual Studio gives me following error:

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

Just to make it clear, I get this error without running any code, just by registering the type provider in visual studio.

When I try to load it from 32 bit fsi I get the same error. But when I try with fsianycpu or 64 bit fsi it works fine. I get my types and auto-completion in 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.

Unfortunately that library only supports 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). Definitely it can't run on a 32 bit machine (or inside a 32 bit process as Visual Studio).

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. 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. 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).

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. 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.

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 ). 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. The price you'll pay is IPC and a big increment of complexity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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