在单个 AppDomain 中多次使用 ComImportAttribute
Multiple usages of ComImportAttribute in a single AppDomain
我有两个库,作为单独的 DLL。这些库不会直接相互引用,但它们有可能存在于同一个 AppDomain 中。
这不是问题(看起来),直到 ComImport[...]
的使用发生冲突。
图书馆1.file1.cs
namespace AudioSwitcher.AudioApi.CoreAudio.Interfaces
{
[ComImport]
[Guid(ComIIds.DEVICE_ENUMERATOR_CID)] //BCDE0395-E52F-467C-8E3D-C4579291692E
internal class MultimediaDeviceEnumeratorComObject
{
}
}
图书馆2.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
"fixes" 本身的第一次使用,以及以后任何使用该 CLSID 创建对象的请求 returns 第一次使用的类型。
这似乎是一个巨大的疏忽,并且在代码中从不同位置连接第三方库时可能会导致意外问题。
有谁知道解决这个问题的方法吗?我通过创建一个未知实例并将其直接转换为已实现的接口来解决这个问题。但这似乎很老套。
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;
}
}
我有两个库,作为单独的 DLL。这些库不会直接相互引用,但它们有可能存在于同一个 AppDomain 中。
这不是问题(看起来),直到 ComImport[...]
的使用发生冲突。
图书馆1.file1.cs
namespace AudioSwitcher.AudioApi.CoreAudio.Interfaces
{
[ComImport]
[Guid(ComIIds.DEVICE_ENUMERATOR_CID)] //BCDE0395-E52F-467C-8E3D-C4579291692E
internal class MultimediaDeviceEnumeratorComObject
{
}
}
图书馆2.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
"fixes" 本身的第一次使用,以及以后任何使用该 CLSID 创建对象的请求 returns 第一次使用的类型。
这似乎是一个巨大的疏忽,并且在代码中从不同位置连接第三方库时可能会导致意外问题。
有谁知道解决这个问题的方法吗?我通过创建一个未知实例并将其直接转换为已实现的接口来解决这个问题。但这似乎很老套。
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;
}
}