com-5调用com组件的方法总结

需求:

1.创建myCom.dll,该COM只有一个组件,两个接口:

IGetRes--方法Hello(),
IGetResEx--方法HelloEx()

2.在工程中导入组件或类型库

clip_image001 #import "组件所在目录myCom.dll" no_namespace

clip_image001   #import "类型库所在目录myCom.tlb"
clip_image001   using namespace MYCOM;

方法一:

1
2
3
4
5
6
7
8
CoInitialize(NULL);
CLSID clsid;
CLSIDFromProgID(OLESTR("myCom.GetRes"), &clsid);
CComPtr<IGetRes> pGetRes;//智能指针
pGetRes.CoCreateInstance(clsid);
pGetRes->Hello();
pGetRes.Release();//小心哦!!请看最后的“注意”
CoUninitialize();

方法二:

1
2
3
4
5
6
7
CoInitialize(NULL);
CLSID clsid;
HRESULT hr = CLSIDFromProgID(OLESTR("myCom.GetRes"), &clsid);
IGetRes* ptr;
hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(IGetRes), (LPVOID*)&ptr);
ptr->Hello();
CoUninitialize();

方法三:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CoInitialize(NULL);
HRESULT hr;
CLSID clsid;
hr = CLSIDFromProgID(OLESTR("myCom.GetRes"), &clsid);
IGetRes* ptr;
IGetResEx* ptrEx;
//使用CoCreateClassObject创建一个组件(特别是mutilThreads)的多个对象的时候,效率更高.
IClassFactory* p_classfactory;
hr = CoGetClassObject(clsid, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (LPVOID*) & p_classfactory);
p_classfactory->CreateInstance(NULL, __uuidof(IGetRes), (LPVOID*)& ptr);
p_classfactory->CreateInstance(NULL, __uuidof(IGetResEx), (LPVOID*)& ptrEx);
ptr->Hello();
ptrEx->HelloEx();
CoUninitialize();


方法四:
直接从dll中得到DllGetClassObject,接着生成类对象及类实例(这方法可以
使组件不用在注册表里注册, 这是最原始的方法, 但这样做没什么意义, 至少失去了COM
对用户的透明性), 不推荐使用.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typedef HRESULT(__stdcall* pfnHello)(REFCLSID, REFIID, void**);
pfnHello fnHello = NULL;
HINSTANCE hdllInst = LoadLibrary("组件所在目录myCom.dll");
fnHello = (pfnHello)GetProcAddress(hdllInst, "DllGetClassObject");
if (fnHello != 0)
{
IClassFactory* pcf = NULL;
HRESULT hr = (fnHello)(CLSID_GetRes, IID_IClassFactory, (void**)&pcf);
if (SUCCEEDED(hr) && (pcf != NULL))
{
IGetRes* pGetRes = NULL;
hr = pcf->CreateInstance(NULL, IID_IFoo, (void**)&pGetRes);
if (SUCCEEDED(hr) && (pFoo != NULL))
{
pGetRes->Hello();
pGetRes->Release();
}
pcf->Release();
}
}
FreeLibrary(hdllInst);