Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 4.0 无法为Google Earth插件获得类型等效_C# 4.0_Com Interop_Type Equivalence - Fatal编程技术网

C# 4.0 无法为Google Earth插件获得类型等效

C# 4.0 无法为Google Earth插件获得类型等效,c#-4.0,com-interop,type-equivalence,C# 4.0,Com Interop,Type Equivalence,我有一个嵌入谷歌EarthGE插件的WinForms C应用程序。这是通过COM互操作来完成的,通过添加对Google Earth插件的引用 我们希望能够在部署应用程序时支持不同版本的GE插件。因此,我们在一台开发机器上参考并构建了针对5.0版GE插件的应用程序,然后部署到另一台安装了6.0版GE插件的机器上,让应用程序使用类型等效运行 根据我对C4.0中包含的类型嵌入和类型等价的理解,这正是类型等价所要解决的问题。然而,我一直无法让这项工作 我在VisualStudio2010中添加了对Goo

我有一个嵌入谷歌EarthGE插件的WinForms C应用程序。这是通过COM互操作来完成的,通过添加对Google Earth插件的引用

我们希望能够在部署应用程序时支持不同版本的GE插件。因此,我们在一台开发机器上参考并构建了针对5.0版GE插件的应用程序,然后部署到另一台安装了6.0版GE插件的机器上,让应用程序使用类型等效运行

根据我对C4.0中包含的类型嵌入和类型等价的理解,这正是类型等价所要解决的问题。然而,我一直无法让这项工作

我在VisualStudio2010中添加了对Google Earth插件5.2的引用,作为COM引用。 我选择“嵌入互操作类型”

然后,我在安装了6.0 GE插件的机器上运行该应用程序

我得到一个运行以下代码行的异常

string pluginVersion = ge.getPluginVersion();
其中ge的定义为:

 private IGEPlugin ge;
“IGEPlugin”是由COM互操作为GE插件DLL定义的接口

System.AccessViolationException未由用户代码处理 消息=尝试读取或写入受保护内存。这通常表示>其他内存已损坏

使用6.0反向生成时,在5.2版上运行时,例外情况有所不同

当构建和运行相同版本的GE插件时,代码和应用程序工作正常

因此,我不确定我遗漏了什么,从MSDN文档来看,它似乎应该自动工作


我真的希望避免在任何地方都使用C4.0“动态”来获得GE插件版本之间的兼容性,因为我失去了所有的智能感知,需要更改很多代码。

我为此挣扎了一段时间。它不使用嵌入互操作类型的原因是Google出于某种原因为COM对象生成了一个全新的GUID,这意味着嵌入的互操作库将不再起作用,即使接口完全相同

我最近遇到了这个问题,GoogleEarth插件决定自动更新自身,从而通过使用新的COM-GUID破坏了互操作兼容性

我知道你不想在任何地方都使用dynamic,因为你失去了IntelliSense-我建议你在最初的开发中使用interop引用,这样你就可以在那个阶段使用静态类型,然后,一旦它足够稳定,就切换到dynamic,您只想确保它在不引发强制转换异常的情况下仍能与Google Earth的未来版本一起工作

我知道你已经知道如何用dynamic解决这个问题,但我在下面发布了我使用的解决方案,也许其他人可以使用它

有了C4.0,您就有了一个简单的解决方案。我解决了这个问题,没有将ge声明为IGEPlugin类型,并删除了项目中对Google Earth的所有引用。相反,声明ge如下:

private dynamic ge;
现在,您可以对ge对象调用任何方法,而无需编译器知道它的确切类型。它将在运行时解决。您只需要确保您正在使用正确的参数调用正确的方法名

如果你能让你的项目在没有任何GEPlugin引用的情况下进行编译,那么你就走上了正确的轨道,一旦我像这样更改它,它对任何Google Earth插件版本都有效

我将发布我用来封装嵌入浏览器控件的插件的类:

[ComVisible(true)]
public class GoogleEarthWebPluginHolder : IGoogleEarthJS {
    dynamic ge = null;
    GoogleEarthWebViewer parent;

    public GoogleEarthWebPluginHolder(GoogleEarthWebViewer parent) {
        this.parent = parent;
    }

    public dynamic Plugin {
        get {
            return ge;
        }
    }

    public void JSInitSuccessCallback_(object pluginInstance) {
        ge = (dynamic)pluginInstance;
        this.parent.JSInitSuccessCallback();
    }

    public void JSInitFailureCallback_(string error) {
        MessageBox.Show("Error: " + error, "Plugin Load Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
    }
}
请注意,构造函数中的父控件是承载浏览器控件和插件的控件。一旦调用了JSInitSuccessCallback,它就会访问插件持有者与GoogleEarth交互。插件持有者的界面看起来像这样,不确定我为什么需要它,但它还是出现了:

[ComVisible(true)]
interface IGoogleEarthJS {
    void JSInitSuccessCallback_(object pluginInstance);
    void JSInitFailureCallback_(string error);
}