2015-11-30 3 views
0

J'ai deux bibliothèques, en tant que DLL séparées. Ces bibliothèques ne se réfèrent jamais directement les unes aux autres, mais il est possible qu'elles puissent exister dans le même AppDomain.Utilisations multiples de ComImportAttribute dans un seul AppDomain

Ce n'est pas un problème (il semble) jusqu'à l'utilisation de ComImport[...] conflits.

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(); 
} 

Exception:

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

Il semble que la première utilisation de ComImport "corrige" lui-même, et toute demande de créer un objet avec ce CLSID dans le futur renvoie ce premier type utilisé. Cela semble être un énorme oubli, et pourrait causer des problèmes inattendus lors de l'interfaçage d'une bibliothèque tierce à partir d'endroits différents dans le code.

Est-ce que quelqu'un connaît un moyen de résoudre ce problème? Je contourne le problème en créant une instance inconnue et en la redirigeant directement vers une interface implémentée. Mais il semble hacky.

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

EDIT: Source (si elle aide): https://github.com/xenolightning/AudioSwitcher

Le problème de travail actuel est dans la branche AudioSession

+0

Il s'agit de 2 classes non apparentées. Vous ne pouvez pas lancer l'un à l'autre. BTW, votre vrai code n'est probablement pas 'var enumerator = new MultimediaDeviceEnumeratorComObject', veuillez écrire le code exact. –

+0

Je sais qu'ils ne sont pas liés. Il n'y a pas de distribution directe entre les deux classes. Il n'y en a pas, car les deux projets ne se réfèrent pas les uns aux autres. C'est le code exact, et exactement ce qui cause le problème. – Xenolightning

+0

Pouvez-vous s'il vous plaît lien directement à cette partie du code sur Github? –

Répondre

0

J'ai fini par ne pas utiliser ComImport et la création d'un ComObject "Factory" à la place. Code pour ladite usine est ci-dessous. Il permet le chargement du même type de com dans différents espaces de noms sans aucun conflit.

internal static class ComObjectFactory 
{ 

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

}