我下面的类型提供程序使用一些本机x64库。我用 anyCpu x64标志编译了我的类型提供程序库。
现在,当我尝试从另一个项目加载我的类型提供程序时,Visual Studio中的IntelliSense会出现以下错误:
类型提供程序'...我的类型提供程序...'报告错误:An 尝试加载具有不正确格式的程序(例外 来自HRESULT:0x8007000B
为了说清楚,我在没有运行任何代码的情况下得到了这个错误,只需在visual studio中注册类型提供程序。
当我尝试从32位fsi
加载它时,我得到了同样的错误。但是,当我尝试使用fsianycpu
或64位fsi
时,它可以正常工作。我在fsi
中获得了我的类型和自动完成功能。
我想这是因为VS自己是x86,IntelliSense /静态代码分析也是x86,在某些时候他们尝试加载依赖于x86 lib的类型提供程序代码并弹出错误。
不幸的是,该库只支持x64。
有没有办法让这项工作在一起?
答案 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,并且复杂性也会大幅增加。