2013-08-07 4 views
3

Je donne les résultats suivants IDL:Puis-je utiliser "exclude" avec la directive # import lorsque je rencontre l'avertissement C4192?

import "oaidl.idl"; 
import "ocidl.idl"; 

[uuid(MyLibUuid), version(1.0)] 
library MyLibrary 
{ 
    importlib("stdole32.tlb"); 
    importlib("stdole2.tlb"); 
[object, uuid("MyInterfaceUuid"), nonextensible] 
interface IMyInterface : IUnknown { 
     HRESULT MyMethod([in] IStream* stream); 
    }; 
} 

qui est compilé dans un fichier .tlb et importé d'un autre projet:

#import "PathToTypeLib.tlb" raw_interfaces_only 

et quand cela est compilé Visual Studio émet la sortie suivante:

warning C4192: automatically excluding 'IStream' 
    while importing type library 'PathToTypeLib.tlb' 
warning C4192: automatically excluding 'ISequentialStream' 
    while importing type library 'PathToTypeLib.tlb' 

D'accord, le problème est que ceux à importlib directives ont causé IStream et ISequentialStream défini à l'intérieur de la typelib - MSDN explains it et dit que je dois soit utiliser include ou no_auto_exclude avec #import.

Si j'utiliser soit no_auto_exclude ou include("IStream", "ISequentialStream") j'ai maintenant deux IStream définitions - un dans l'espace global et un autre dans l'espace de noms typelib et mon code qui essaie d'appeler MyMethod ne compile pas - le compilateur dit

error C2664: 'MyLibrary::MyInterface::MyMethod' : 
    cannot convert parameter 1 from 'IStream *' to 'MyLibrary::IStream *' 
    Types pointed to are unrelated; conversion requires reinterpret_cast, 
    C-style cast or function-style cast 

donc il semble que je devrais plutôt utiliser exclude("IStream", "ISequentialStream") - de cette façon, il compile bien et semble fonctionner.

L'utilisation de exclude utilise-t-elle réellement la bonne solution?

+1

Soit l'utilisation exclut ou no_namespace. Favor exclure. –

Répondre

0

Cela fonctionnerait bien si IStream lui-même était sur une bibliothèque de type, tel que stdole2.tlb vous référencez à partir de votre IDL/TLB. Malheureusement, ce n'est pas le cas et ce qui se passe est que l'ID: compilateur doit mettre votre IMyInterface sur le bloc de la bibliothèque et puisque le IStream est référencé, le compilateur le met également sur la bibliothèque de types. Par conséquent, la déclaration dupliquée vous blesse une fois que vous avez réimporté la bibliothèque de types. Je ne pense pas que vous pouvez l'avoir comme IStream sans prendre votre propre interface IStream sur la bibliothèque de types.

La solution de contournement que j'utilise est d'éviter d'utiliser IStream sur les paramètres de méthode, et d'utiliser IUnknown à la place. L'appelant et l'appelé lancent/QI les pointeurs si/quand cela est approprié. De cette façon, il est sûr avec #import et fonctionne en général.

[uuid(MyLibUuid), version(1.0)] 
library MyLibrary 
{ 
    importlib("stdole32.tlb"); 
    importlib("stdole2.tlb"); 
[object, uuid("MyInterfaceUuid"), nonextensible] 
interface IMyInterface : IUnknown { 
     HRESULT MyMethod([in] IUnknown* pStreamUnkown); // Instead of IStream 
    }; 
} 

appelant:

CComPtr<IStream> pStream; 
pMyInterface->MyMethod(pStream); 

Callee:

STDMETHOD(MyMethod)(IUnkown* pStreamUnknown) 
{ 
    CComQIPtr<IStream> pStream = pStreamUnknown; 

Callee en supposant qu'aucun marshaling (moins de tête):

STDMETHOD(MyMethod)(IUnkown* pStreamUnknown) 
{ 
    ATLASSERT((IUnknown*) (IStream*) CComQIPtr<IStream>(pStreamUnknown) == 
     pStreamUnknown); 
    const CComPtr<IStream>& pStream = 
     reinterpret_cast<const CComPtr<IStream>&>(pStreamUnknown); 
+0

Ouch. Ce dernier extrait est Bad Idea entre de mauvaises mains et Murphy s'assurera qu'il entre des centaines de mauvaises mains. – sharptooth

+0

J'ai lu votre réponse deux fois et je ne comprends pas pourquoi l'utilisation de 'exclure 'ne résout pas le problème. – sharptooth

+0

Avec 'exclude', vous apportez toujours une déclaration inutile' IStream' sur la bibliothèque de types, puis vous excluez les correctifs à l'autre extrémité.Sans parler du fait qu'il existe de nombreuses autres interfaces qui pourraient nécessiter le même hack et que la bibliothèque de types devient de plus en plus lourde. L'utilisation de 'IUnknown' garde la bibliothèque de types exempte de courrier indésirable. –

Questions connexes