sieglej
asked on
Using a VB based COM object from VC++
I have a COM object available as a DLL. The COM is authored in VB. How do I incorporate this COM object into VC++?
My code looks something like this:
struct IDB: public IUnknown
{
STDMETHOD_(void, OpenDB) () = 0;
STDMETHOD_(char*, ErrorMsgOut) () = 0;
};
static const IID IID_IDB =
{ 0x06122e34, 0x82ba, 0x11d2, { 0xbc, 0xc4, 0x00, 0x60, 0x97, 0x50, 0xcb, 0x8d } };
funct(void)
{
CLSID clsid;
LPCLASSFACTORY pClf;
LPUNKNOWN pUnk;
IDB* pDB;
HRESULT hr;
if ((hr = ::CLSIDFromProgID(L"Histo. ClsHisto", &clsid)) != NOERROR) {
TRACE("unable to find Program ID -- error = %x\n", hr);
return;
}
if ((hr = ::CoGetClassObject(clsid, CLSCTX_INPROC_SERVER,
NULL, IID_IClassFactory, (void **) &pClf)) != NOERROR) {;
TRACE("unable to find CLSID -- error = %x\n", hr);
return;
}
pClf->CreateInstance(NULL, IID_IUnknown, (void**) &pUnk);
pUnk->QueryInterface(IID_I DB, (void**) &pDB); // All three
pDB->OpenDB();
char * msg = pDB->ErrorMsgOut();
pClf->Release();
pUnk->Release();
pDB->Release();
AfxMessageBox(msg);
}
Is this the best way to do this? I get pointers to the interface but the functions (OpenDB, GetMsg) don't execute. I'm not sure I'm using the correct GUID for the interface. I'm using the ID for the class within the object. I'm a little confused on which registry values to use.
Thanks,
Jeff
My code looks something like this:
struct IDB: public IUnknown
{
STDMETHOD_(void, OpenDB) () = 0;
STDMETHOD_(char*, ErrorMsgOut) () = 0;
};
static const IID IID_IDB =
{ 0x06122e34, 0x82ba, 0x11d2, { 0xbc, 0xc4, 0x00, 0x60, 0x97, 0x50, 0xcb, 0x8d } };
funct(void)
{
CLSID clsid;
LPCLASSFACTORY pClf;
LPUNKNOWN pUnk;
IDB* pDB;
HRESULT hr;
if ((hr = ::CLSIDFromProgID(L"Histo.
TRACE("unable to find Program ID -- error = %x\n", hr);
return;
}
if ((hr = ::CoGetClassObject(clsid, CLSCTX_INPROC_SERVER,
NULL, IID_IClassFactory, (void **) &pClf)) != NOERROR) {;
TRACE("unable to find CLSID -- error = %x\n", hr);
return;
}
pClf->CreateInstance(NULL,
pUnk->QueryInterface(IID_I
pDB->OpenDB();
char * msg = pDB->ErrorMsgOut();
pClf->Release();
pUnk->Release();
pDB->Release();
AfxMessageBox(msg);
}
Is this the best way to do this? I get pointers to the interface but the functions (OpenDB, GetMsg) don't execute. I'm not sure I'm using the correct GUID for the interface. I'm using the ID for the class within the object. I'm a little confused on which registry values to use.
Thanks,
Jeff
The best way is opening the ClassWizard, selecting 'New Class' and choose 'From TypeLib'. Then, supply your dll as the source for the type library, and VC++ should generate the necessary wrapper classes...
Ooops, sorry, i have been a bit on the MFC path...
Well, usually VC uses IDispatch, which is usually created like this:
sc = ::CoCreateInstance ( clsid,
NULL,
CLSCTX_SERVER,
IID_IDispatch,
( void**) &pDB
);
then, the methods are usually called using the 'Invoke()' method of an IDispatch.
If you have a _real_ COM interface (different from IDispatch), the IDL code could be helpful...
Well, usually VC uses IDispatch, which is usually created like this:
sc = ::CoCreateInstance ( clsid,
NULL,
CLSCTX_SERVER,
IID_IDispatch,
( void**) &pDB
);
then, the methods are usually called using the 'Invoke()' method of an IDispatch.
If you have a _real_ COM interface (different from IDispatch), the IDL code could be helpful...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Do you have an example of using #import in VC++? All I have provided to me is a DLL file.