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(B STR data, int terminal, BSTR *Message)
{
AFX_MANAGE_STATE(AfxGetSta ticModuleS tate())
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- AD65BEFC66 1D}'
}
RFComDll.ProcessREQ = s 'ProcessREQ Class'
{
CLSID = s '{50FA39B5-290B-46CC-B950- AD65BEFC66 1D}'
CurVer = s 'RFComDll.ProcessREQ.1'
}
NoRemove CLSID
{
ForceRemove {50FA39B5-290B-46CC-B950-A D65BEFC661 D} = 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- FA2616426D A4}'
}
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(L PCTSTR 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 .ProcessRE Q.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
STDMETHODIMP CProcessREQ::DispatchReq(B
{
AFX_MANAGE_STATE(AfxGetSta
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-
}
RFComDll.ProcessREQ = s 'ProcessREQ Class'
{
CLSID = s '{50FA39B5-290B-46CC-B950-
CurVer = s 'RFComDll.ProcessREQ.1'
}
NoRemove CLSID
{
ForceRemove {50FA39B5-290B-46CC-B950-A
{
ProgID = s 'RFComDll.ProcessREQ.1'
VersionIndependentProgID = s 'RFComDll.ProcessREQ'
ForceRemove 'Programmable'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Both'
}
'TypeLib' = s '{C1B9CF16-CA21-4677-A492-
}
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(L
{
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
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
ASKER
Carl