Link to home
Start Free TrialLog in
Avatar of carlmahon
carlmahon

asked on

Adding a COM DLL from a tlb/dll via Add New Class wizard (VC 6.0) and accessing methods

I have created a ATL/Com DLL (rfcomdll.dll) and registered it. It has one method (at this time) called DispatchReq (code excerpt below).

STDMETHODIMP CProcessREQ::DispatchReq(BSTR data, int terminal, BSTR *Message)
{
         AFX_MANAGE_STATE(AfxGetStaticModuleState())
         CComBSTR str;
         str = "Hello";
         str += data;
        *Message = str.Detach();
        return S_OK;
}

The COM object has the following registry....

RFComDll.ProcessREQ.1 = s 'ProcessREQ Class'
{
 CLSID = s '{50FA39B5-290B-46CC-B950-AD65BEFC661D}'
}
RFComDll.ProcessREQ = s 'ProcessREQ Class'
{
CLSID = s '{50FA39B5-290B-46CC-B950-AD65BEFC661D}'
CurVer = s 'RFComDll.ProcessREQ.1'
}
NoRemove CLSID
{
ForceRemove {50FA39B5-290B-46CC-B950-AD65BEFC661D} = s 'ProcessREQ Class'
{
ProgID = s 'RFComDll.ProcessREQ.1'
VersionIndependentProgID = s 'RFComDll.ProcessREQ'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{C1B9CF16-CA21-4677-A492-FA2616426DA4}'
}

I created a SDI VC++ exe project that I want to access the COM object from.

I added the COM class via the Add New Class wizard (using the tlb - type library) which has created the class (cpp & h files) in my project. Below is an excerpt of the cpp file with the helper code that class wizard created.

CString IProcessREQ::DispatchReq(LPCTSTR data, long terminal)
{
      CString result;
      static BYTE parms[] =
            VTS_BSTR VTS_I4;
      InvokeHelper(0x1, DISPATCH_METHOD, VT_BSTR, (void*)&result, parms,
            data, terminal);
      return result;
}


I have the following code in a the main view of my project called MyClient...

MyClient::ExecuteMethod()
{
CString s;
IProcessREQ r;
COleException *e = new COleException;

r.CreateDispatch("RFComDll.ProcessREQ.1",e);
s = r.DispatchReq("MyData",1);
}

This code is failing partially because the m_lpDispatch class member is NULL among other problems. I badly assumed that by using class wizard I could access the method without issue. What is the best way to do this?

Carl
SOLUTION
Avatar of OnegaZhang
OnegaZhang

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of carlmahon
carlmahon

ASKER

The MFC framework must be calling AfxOleInit() already.  If I call AfxOleInit() before CreateDispatch() it causes an assertion error and I can see in the debugger that it has already been called at some point during program initialization. So calling that function a second time is not helping.

Carl
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
After some testing here is what I found after I watched the code in the debugger...

When compiling the COM dll, VCC was performing the registration after the DLL was compiled. I was not getting any errors in the compile output so I assumed it registered. I wanted to check that the registration was really happening so I used regsvr32 and component services to manually register the component.  Both of those failed (even if the DLL was previously unregistered using regsvr32 /u). After some research on the Microsoft KB I discovered that the atl.dll had not been registered on my system which is required for VC++6.0. (Not sure whay it was ever unregistered). After I registered the atl.dll I could then register and access the component.

My original coding worked without using the CoInitialize(0) answer provided by nonubik, but it may also have been automatically called within MFC framework, I do not know. Since I did not indicate that there could have been COM registration issue I will split the points as an assist from both. At least once I started looking at those functions in the debugger it led me to realize that the DLL just wasn't there.

Carl