【问题标题】:Multiple usages of ComImportAttribute in a single AppDomainComImportAttribute 在单个 AppDomain 中的多种用法
【发布时间】:2015-11-30 09:55:23
【问题描述】:

我有两个库,作为单独的 DLL。这些库不会直接相互引用,但它们有可能存在于同一个 AppDomain 中。

在使用 ComImport[...] 冲突之前,这不是问题(似乎)。

library1.file1.cs

namespace AudioSwitcher.AudioApi.CoreAudio.Interfaces
{
    [ComImport]
    [Guid(ComIIds.DEVICE_ENUMERATOR_CID)] //BCDE0395-E52F-467C-8E3D-C4579291692E
    internal class MultimediaDeviceEnumeratorComObject
    {
    }
}

library2.file2.cs

namespace AudioSwitcher.AudioApi.Hooking.ComObjects
{
    [ComImport]
    [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
    internal class MultimediaDeviceEnumeratorComObject
    {
    }
}

library2.somefile.cs

public void GetObject()
{
    //throws unable to cast exception
    var enumerator = new MultimediaDeviceEnumeratorComObject();
}

例外:

Unable to cast object of type 'AudioSwitcher.AudioApi.CoreAudio.Interfaces.MultimediaDeviceEnumeratorComObject' to type 'AudioSwitcher.AudioApi.Hooking.ComObjects.MultimediaDeviceEnumeratorComObject'.

似乎ComImport 的第一次使用“修复”了自身,并且将来创建具有该 CLSID 的对象的任何请求都会返回第一次使用的类型。

这似乎是一个巨大的疏忽,并且在从代码中的不同位置连接第三方库时可能会导致意外问题。

有人知道解决这个问题的方法吗?我通过创建一个未知实例并将其直接转换为已实现的接口来解决此问题。但它看起来很hacky。

Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"))) as IMultimediaDeviceEnumerator;

编辑: 来源(如果有帮助):https://github.com/xenolightning/AudioSwitcher

当前的工作问题在 AudioSession 分支中

【问题讨论】:

  • 这是 2 个不相关的类。你不能把一个投给另一个。顺便说一句,您的真实代码可能不是var enumerator = new MultimediaDeviceEnumeratorComObject,请发布确切的代码。
  • 我知道它们是无关的。两个类之间没有直接转换。不可能,因为这两个项目不相互引用。那是确切的代码,正是它导致问题的原因。
  • 你能直接链接到 Github 上的那部分代码吗?
  • github.com/xenolightning/AudioSwitcher/commit/… 拥有所有相关详细信息。该代码目前在 DefaultDeviceHook.cs 中被注释掉
  • 所以第 105 行正在抛出?不是在 105 到 119 之间吗?

标签: c# .net com appdomain


【解决方案1】:

我最终没有使用ComImport 而是创建了一个 ComObject“工厂”。所述工厂的代码如下。它允许在不同的命名空间中加载相同的 com 类型而不会发生任何冲突。

internal static class ComObjectFactory
{

    public static IMultimediaDeviceEnumerator GetDeviceEnumerator()
    {
        return Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(ComIIds.DEVICE_ENUMERATOR_CID))) as IMultimediaDeviceEnumerator;
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多