如何在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.不过,好像有些多此一举。
可以有很多方法生成一个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.不过,好像有些多此一举。