在单个AppDomain中使用ComImportAttribute的多个用法

时间:2015-11-30 09:55:24

标签: c# .net com appdomain

我有两个库,作为单独的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创建对象的任何请求都会返回首次使用的类型。

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

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

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

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

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

1 个答案:

答案 0 :(得分:0)

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

internal static class ComObjectFactory
{

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

}