2011-09-18 4 views
0

J'utilise un composant COM natif externe dans mon application C# .Net.Comment gérer les paramètres de création d'objet RCW COM de .Net (à savoir l'interface requise)?

Cette DLL COM ne possède pas de bibliothèque de types, j'ai donc dû écrire moi-même le code d'interopérabilité, et ayant des fichiers include/idl je l'ai fait comme TlbImp. Mais le pire est que la création d'objets échouent avec:

Création d'une instance du composant COM avec CLSID {40700425-0080-11D2-851F-00C04FC21759} du IClassFactory a échoué en raison de l'erreur suivante: 80040111

La classe est finement créée si j'utilise CoCreateInstance natif et spécifie class_id et l'un des iids d'interface implémentés. Il s'est avéré que le problème réside dans le fait que IClassFactory :: CreateInstance de l'objet COM ne supporte pas IID_IUnknown passé comme paramètre riid, et renvoie donc CLASS_E_CLASSNOTAVAILABLE (je l'ai identifié avec le désassembleur et le débogueur). Le composant est MS SQL VDI.

Existe-t-il un moyen de forcer .Net RCW à transmettre un ID d'interface différent à la méthode CreateInstance plutôt qu'à IID_IUnknown? La recherche a été très poussée, mais elle n'a pas trouvé de solution.

En guise de solution de contournement, j'utilise maintenant C++/CLI pour créer un objet en demandant l'interface appropriée à la place si IID_IUnknown. à cet effet maintenant, mais aimerait avoir du code en C#, car C++/CLI me demande de construire des DLL différentes pour chaque plate-forme.

Merci

+0

Ne pas répondre à IUnknown de CoCreateInstance() est un bogue. Pouvez-vous obtenir les propriétaires de la bibliothèque externe pour le réparer? http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx –

+0

Les propriétaires sont Microsoft, et depuis ce bug existe depuis plus de 10 ans et en tenant compte du fait qu'il doesn Ne pas bloquer l'utilisation des composants Je ne pense pas que le patch sera disponible – mistika

+0

Oh, wow. C'est génial. –

Répondre

0

Je repro. Brr, douloureux. Vous pouvez épingler CoCreateInstance:

[return: MarshalAs(UnmanagedType.Interface)] 
[DllImport("ole32.dll", ExactSpelling=true, PreserveSig=false)] 
public static extern object CoCreateInstance(ref Guid clsid, 
    [MarshalAs(UnmanagedType.Interface)] object punkOuter, int context, ref Guid iid); 
+0

Merci beaucoup pour votre suggestion, Hans. Ça fait l'affaire, et le simple rappeur va le cacher. Bien qu'il serait agréable d'avoir quelque chose comme (edit - Dieu, comment afficher un saut de ligne dans le commentaire? NBoth Enter et CtrlEnter appuie sur le bouton Enregistrer). ... quelque chose comme: [DefaultInterfaceGuid ("XXXX-XXX-XXX")] ou plus. – mistika

+0

Vous pouvez utiliser 'pour citer le code. –

Questions connexes