2009-10-01 6 views
0

J'ai une DLL basée sur ATL/COM, faite en utilisant VC++ 6.0. Il est utilisé pour divers exécutables construits en utilisant VB6.ATL/COM: Définition d'une interface COM qui ne sera pas disponible en dehors de la DLL?

Je souhaite ajouter certaines interfaces COM qui ne seront pas accessibles via VB6, pour l'utilisation interne de la DLL uniquement. Je veux qu'ils soient des interfaces COM plutôt que simplement des interfaces C++ du fait que je les utiliserai sur des objets auxquels je n'ai que des références d'interface COM (au moment de l'utilisation). C'est-à-dire, je ne sais pas (au moment de l'utilisation) que ce pointeur pointe vers un CFoo; Je sais juste qu'il pointe vers un IFoo, où IFoo est une interface COM, publiée pour que VB6 le sache. A partir de ce pointeur IFoo, je veux obtenir un pointeur IFooInternal, que chaque classe implémentant IFoo (et pas seulement CFoo) va implémenter. De plus, je ne veux pas que IFooInternal soit accessible en dehors de la DLL elle-même; Par exemple, je ne veux pas que IFooInternal soit accessible par VB6.

Toute aide avec ceci serait grandement appréciée. Suggestions pour d'autres moyens d'atteindre le même objectif global serait également. Merci d'avance.

+0

Dupliquer http://stackoverflow.com/questions/1191012/how-to-prevent-coclass-implementations-from-being-exposed-in-an-atl-type-library/1192207#1192207 –

+0

Ce n'est pas * * un duplicata de la question à laquelle vous avez lié. Dans cette question, l'interface sera exposée à Visual Basic (et autres clients en dehors de la DLL elle-même). C'est exactement ce que j'essaie d'éviter *. –

Répondre

1

Répondre à ma propre question pour le bénéfice de toute personne qui trouve ce fil dans le futur. Cependant, s'il vous plaît noter que je devine juste ici, basé sur l'expérimentation ... il semble fonctionner, au moins dans ma situation spécifique, mais je ne sais pas.

Tout d'abord, dans un fichier d'en-tête approprié (peut-être Hidden.h), mettre ce qui suit, en remplaçant un nouveau produit UUID avec un UUID nouvellement généré:

#ifndef __Hidden_h__ 
#define __Hidden_h__ 

extern "C" { 

#ifndef __IHidden_FWD_DEFINED__ 
#define __IHidden_FWD_DEFINED__ 
typedef interface IHidden IHidden; 
#endif // __IHidden_FWD_DEFINED__ 

#ifndef __IHidden_INTERFACE_DEFINED__ 
#define __IHidden_INTERFACE_DEFINED__ 

EXTERN_C const IID IID_IHidden; 

MIDL_INTERFACE("a newly generated UUID") 
IHidden : public IUnknown 
{ 
    public: 
     virtual HRESULT STDMETHODCALLTYPE get_Something (
      long __RPC_FAR *pVal) = 0; 
}; 

#endif // __IHidden_INTERFACE_DEFINED__ 

} 

#endif // __Hidden_h__ 

Pour savoir comment définir d'autres types de paramètres et similaires pour une fonction, reportez-vous à l'en-tête C++ qui a été généré par MIDL à partir de votre fichier IDL.

Ensuite, dans l'en-tête pour toutes les classes que vous souhaitez implémenter cette interface, ajouter l'interface à la déclaration de classe:

class ATL_NO_VTABLE CBlah : 
    public CComObjectRootEx<CComSingleThreadModel>, 
    public CComCoClass<CBlah, &CLSID_CBlah>, 
    public ISupportErrorInfo, 
    public IConnectionPointContainerImpl<CBlah>, 
    public IBlah, 
    public IHidden 

ajouter également à la COM_MAP:

BEGIN_COM_MAP(CBlah) 
    COM_INTERFACE_ENTRY(IBlah) 
    COM_INTERFACE_ENTRY(ISupportErrorInfo) 
    COM_INTERFACE_ENTRY(IConnectionPointContainer) 
    COM_INTERFACE_ENTRY(IHidden) 
END_COM_MAP 

Et à partir de là, il suffit d'ajouter les déclarations C++ standard et les définitions des fonctions de l'interface à la classe:

public: 
    STDMETHOD(get_Something)(long *pVal); 

(...)

STDMETHODIMP CBlah::get_Something(long *pVal) 
{ 
    if (!pVal) 
    { 
     (error handling) 
    } 

    *pVal = 37; 

    return S_OK; 
} 

J'espère que cela aide quelqu'un à l'avenir. J'espère aussi que ça ne me blesse pas parce que c'est incorrect. Comme je l'ai dit, cependant, cela semble fonctionner.

Questions connexes