在单个AppDomain中多次使用ComImportAttribute
本文关键字:ComImportAttribute 单个 AppDomain | 更新日期: 2023-09-27 18:24:58
我有两个库,作为单独的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分支
我最终没有使用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;
}
}