Solved

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

Posted on 2004-10-17
4
365 Views
Last Modified: 2013-11-25
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
0
Comment
Question by:carlmahon
  • 2
4 Comments
 
LVL 12

Assisted Solution

by:OnegaZhang
OnegaZhang earned 250 total points
ID: 12336130
call AfxOleInit() before CreateDispatch

welcome to www.fruitfruit.com
0
 
LVL 4

Author Comment

by:carlmahon
ID: 12336356
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
0
 
LVL 16

Accepted Solution

by:
nonubik earned 250 total points
ID: 12336458
Note   If AfxOleInit is called from an MFC DLL, the call will fail. The failure occurs because the function assumes that, if it is called from a DLL, the OLE system was previously initialized by the calling application.

You should try calling CoInitialize(0) or CoInitializeEx(0, COINIT_APARTMENTTHREADED) before using COM. And for each successfull CoInitialize, call CoUninitalize when done with COM. Be carefull not to call them from DllMain (or CWinApp derived class InitInstance/Exitinstance methods).
0
 
LVL 4

Author Comment

by:carlmahon
ID: 12341158
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
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now