现在从别人那里拿到了一个DLL, 其中是一个COM组件,并且定义了一个“出”接口,即客户要实现这个接口,然后传递回去。我现在只有这个DLL,我用ole view得到了一个IDL文件,但是我怎么样实现这个接口呢?

解决方案 »

  1.   

    使用VC自带的MIDL.EXE、Mktyplib.exe程序生成库,导入工程使用。
      

  2.   

    http://www.vckbase.com/document/viewdoc/?id=915
    楼主看看!
      

  3.   

    Add a <project_name>.idl file to the project and set up a custom rule to invoke the MIDL compiler to generate the <project_name>.tlb, project>_i.h, and <project>_i.c files. For example: 
    midl /Oicf /h "<project_name>_i.h" /iid "<project_name>_i.c"
           "<project_name>.idl"You can find more in msdn.
      

  4.   

    你的问题:客户要实现这个接口,然后传递回去
    方    法: 接口着色(简单说明:接口的名字不一样,但内存布局一样)过   程:
    1.定义一个纯虚基类,名字随意,内存布局和ole view看到的接口内存布局要一致
    2.派生并实现这个纯需基类
    使用举例:  
    1.( DLL中的接口IHappyParrot,他有一个的方法Sleep() )
    2.在你的客户派生并实现IHappyParrot
      class  CHappyParrot : public IHappyParrot
     {
         Sleep() //实现Sleep方法,如果还有其他方法必须都实现
     }
    3.HRESULT UseCurstomInterface(IHappyParrot* pParrot);组件方法
    4.CHappyParrot HappyParrot
      sp->UseCurstomInterface ( (IHappyParrot*)& HappyParrot);
    5.OK很简单吧,VCKBASE上,老杨头有讲解的
    本来下午就看到你的帖子,可开会开到妈的快6点多,老婆烧的菜都凉了~~~~~~~~~
      

  5.   

    补充一点:
    COM组件的基本特性必须实现,AddRef,Release,QueryInterface你可以按 老杨头 的说法做也可以使用ATL的类CComObject
      

  6.   

    使用举例:  
    1.( DLL中的接口IHappyParrot,他有一个的方法Sleep() )
    2.在你的客户派生并实现IHappyParrot
      class  CHappyParrot : public IHappyParrot
     {
         Sleep() //实现Sleep方法,如果还有其他方法必须都实现
     }
    靠,谁这么拍鸟人
      

  7.   

    今天看到很了很多帖子可怜HappyParrot俺的老乡,怎么这么多人都BS you 呢?~~~~~
    尤其那个laomai~~~~~~~~~~~~~~~~~~~~~~~
      

  8.   

    这次把问题写明白一些: 如果哪位需要代码可以把邮件留下,这个问题解决之后我会写一个详细的说明,并且把代码放出来,因为很多人在做屏幕取词,用金山词霸的这个DLL是比较简单的一个方法。
    1 金山词霸2005中有一个XdictGrb.dll,是一个COM组件,实现了屏幕取词的功能,现在我想拿来用用,:)2 这个COM组件中有几个接口,大家可以参考以下网址3 我自己写了一个IXDictGrabSink的定义,内存布局应该是和生成的IDL一样的   static const IID IID_IXDictGrabSink =
    { 0xA06978CE, 0x8077, 0x4470, { 0xAA,0xBC,0x2A,0x10,0x01,0xDC,0x5D,0xE4 } };interface   IXDictGrabSink : public IDispatch
        {
        public:
            virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE QueryWord( 
                /* [in] */ BSTR WordString,
                /* [in] */ long lCursorX,
                /* [in] */ long lCursorY,
                /* [in] */ BSTR SentenceString,
                /* [out][in] */ long __RPC_FAR *lLoc,
                /* [out][in] */ long __RPC_FAR *lStart,
                /* [retval][out] */ long __RPC_FAR *lLens) = 0;
            
        };   其中IID_IXDictGrabSink 的值是IDL中这个街口的IID,不是自己新生成的。4  我现在定义了下面这样一个类来实现IXDictGrabSink接口
        //定义
        class CMyGrabSink : public CCmdTarget
    {
    DECLARE_DYNCREATE(CMyGrabSink)
    CMyGrabSink();          
    public:
    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMyGrabSink)
    public:
    virtual void OnFinalRelease();
    //}}AFX_VIRTUAL
    // Implementation
    protected:
    virtual ~CMyGrabSink();
    // Generated message map functions
    //{{AFX_MSG(CMyGrabSink)
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    // Generated OLE dispatch map functions
    //{{AFX_DISPATCH(CMyGrabSink)
    afx_msg HRESULT QueryWord(BSTR WordString,long lCursorX,long lCursorY,
    BSTR SentenceString,long FAR *lLoc,
    long FAR *lStart,long FAR *lLens);
    //}}AFX_DISPATCH
    DECLARE_DISPATCH_MAP()
    DECLARE_INTERFACE_MAP()
    };////////////////////////////////////////////////////////////////////////////
    //实现
    IMPLEMENT_DYNCREATE(CMyGrabSink, CCmdTarget)CMyGrabSink::CMyGrabSink()
    {
    EnableAutomation();
    AfxOleLockApp();
    }CMyGrabSink::~CMyGrabSink()
    {
         AfxOleUnlockApp();
    }
    void CMyGrabSink::OnFinalRelease()
    {
    CCmdTarget::OnFinalRelease();
    }
    BEGIN_MESSAGE_MAP(CMyGrabSink, CCmdTarget)
    END_MESSAGE_MAP()BEGIN_DISPATCH_MAP(CMyGrabSink, CCmdTarget)
    DISP_FUNCTION( CMyGrabSink, _T("QueryWord"),  QueryWord,VT_I4,  
                          VTS_BSTR VTS_I4 VTS_I4 VTS_BSTR VTS_PI4 VTS_PI4 VTS_PI4 )
    END_DISPATCH_MAP()BEGIN_INTERFACE_MAP(CMyGrabSink, CCmdTarget)
    INTERFACE_PART(CMyGrabSink, IID_IXDictGrabSink, Dispatch)
    END_INTERFACE_MAP()HRESULT CMyGrabSink::QueryWord(
    /* [in] */ BSTR WordString,
    /* [in] */ long lCursorX,
    /* [in] */ long lCursorY,
    /* [in] */ BSTR SentenceString,
    /* [out][in] */ long FAR *lLoc,
    /* [out][in] */ long FAR *lStart,
    /* [retval][out] */ long FAR *lLens)
    {
    AfxMessageBox(_T("DONE!"));
    return S_OK;
    }5 这一步中需要调用金山词霸DLL中的一个接口IGrabProxy的方法AdviseGrab,用我们自己定义的接口的一个实现来作为参数传递过去, 首先我用class wizard中的add class (from typelib)来生成一个新类IGrabProxy, 其定义如下:
      class IGrabProxy : public COleDispatchDriver
    {
    public:
    IGrabProxy() {} // Calls COleDispatchDriver default constructor
    IGrabProxy(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
    IGrabProxy(const IGrabProxy& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}// Attributes
    public:// Operations
    public:
    long GetGrabInterval();
    void SetGrabInterval(long nNewValue);
    long GetGrabMode();
    void SetGrabMode(long nNewValue);
    long GetGrabFlag();
    void SetGrabFlag(long nNewValue);
    BOOL GetGrabEnabled();
    void SetGrabEnabled(BOOL bNewValue);
    long GetGrabSystemCP();
    void SetGrabSystemCP(long nNewValue);
    void GrabWord(long lCursorX, long lCursorY);
    long AdviseGrab(LPDISPATCH XDictGrabSink);
    void UnadviseGrab(long lCookie);
    LPDISPATCH GetXDictGrabPlugins();
    };6 在程序初始化的时候,把我们的接口传递过去:
    IGrabProxy iGrabProxy;
    iGrabProxy.CreateDispatch(CLSID_GrabProxy);m_dwCookie = 0;
    if(&iGrabProxy != NULL)
    {
             iGrabProxy.SetGrabMode(XDictGrabMouseWithCtrl);
    long x = iGrabProxy.GetGrabMode();
    LPDISPATCH pDisp;
    m_pGrabSink = new CMyGrabSink();
    m_pGrabSink->InternalQueryInterface(&IID_IDispatch,(void**)&pDisp);
    if(pDisp != NULL)
    {
    m_dwCookie = iGrabProxy.AdviseGrab(pDisp);
    }
    }
      

  9.   

    关于这个COM组件实现的接口,大家可以参考一下这个网址,刚才忘了贴上去了:http://spaces.msn.com/members/tongxiaofeng/Blog/cns!1pR_PsQz7rPcW32aavcleDGQ!372.entry
      

  10.   

    http://www.vckbase.com/document/viewdoc/?id=1526