如何在MFC客户端调用COM DLL

也许有人会认为这是一个非常小儿科的问题。不过,我还是颇花费了一点时间和精力才搞清楚的。OK, 下面简单谈一下如何去做。
可以有很多方法生成一个COM DLL。比如,VB, VC++, DELPHI等等。由于笔者只略通VB和VC,就只用他们作例子了。

(一)VC生成的DLL
如果是VC生成的DLL,通常你可以通过该DLL的TLB(Type Library)在MFC客户端调用该DLL.
假设DLL的tlb文件是testATL.tlb,该DLL的IDL文件内容如下:
import "oaidl.idl";
import "ocidl.idl";

    [
        object,
        uuid(0A2E8C16-7043-4FE9-8AF1-545E88EDBE14),
        dual,
        helpstring("ItestATLx Interface"),
        pointer_default(unique)
    ]
    interface ItestATLx : IDispatch
    {
       
        [id(1), helpstring("method addLong")] HRESULT addLong([in] long x, [out, retval] long *y);
    };

[
    uuid(AD75C4D3-958D-4A31-9BB7-512A8B4CCB60),
    version(1.0),
    helpstring("testATL 1.0 Type Library")
]
library TESTATLLib
{
    importlib("stdole32.tlb");
    importlib("stdole2.tlb");

    [
        uuid(94BE9EF2-D9F9-469B-BFF4-5ABA71DADC38),
        helpstring("testATLx Class")
    ]
    coclass testATLx
    {
        [default] interface ItestATLx;
    };
};
你只要在MFC客户端加入如下代码就可了。
1)
#import "..\testATL\testATL.tlb"     //..\testATL是客户端的相对路径
using namespace TESTATLLib;
且慢,这段代码加到哪里呢?他们只能位于下面#endif之上和注释之下。否则,嘿嘿。。。
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_XXXDLG_H__CDD4B4C8_59E6_4C9C_BDF8_2820FF496074__INCLUDED_)
2)
接下来,就可以声明DLL中的类和调用其中的方法了。
    ItestATLxPtr test(__uuidof(testATLx));
    long y=test->addLong(8);
ItestATLxPtr是什么鬼东西?简单,就是你的DLL中coclass Interface的指针。如果你的Interface是ItestATLx,他就是ItestATLxPtr.如果他是InormalCom,那他就是 InormalComPtr. testATLx吗,不用我说你也知道,coclass! 好了,通过ItestATLxPtr test(__uuidof(testATLx))你就获得一个test,通过它你就可以调用DLL中的function了。
奥,还有就是别忘了在这段代码前后调用CoInitialize()和CoUninitialize()。他们的作用我就不说了。什么不清楚?!·#¥%…………—?
(二)VB生成的DLL
其实VB生成的COM DLL和VC生成COM DLL基本类似(废话,不都是实现了COM接口吗)。如果说有区别的话,VB生成的COM DLL自包含了type library.这样MFC的代码就稍有不同了。(我只是从codeproject摘录了VB的部分,你可从http: //www.codeproject.com/dll/vbactivexwithvc.asp阅读Amit Dey的文章)
1)
# import "prjdll.dll"
using namespace prjdll;
当然也必须放在那个奇怪的地方。
2)
HRESULT hresult;
CLSID clsid;

CoInitialize(NULL);    //initialize COM library
hresult=CLSIDFromProgID(OLESTR("prjdll.clsdll"), &clsid);    //retrieve CLSID of component
       
_clsdll *t;
hresult=CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,__uuidof(_clsdll),(LPVOID *) &t);
if(FAILED(hresult))
{
    AfxMessageBox("Creation Failed");
    return;
}
t->fnCallDll ();  //call method
t->Release();   //call method
CoUninitialize();  //Unintialize the COM library

(三)其他
其实,你也可以通过CLSIDFromProgID调用VC生成的COM DLL.不过,好像有些多此一举。




posted on 2005-03-22 16:26  Michael Zhao  阅读(4877)  评论(1编辑  收藏  举报