Debugging In-Process COM Servers

 < Free Open Study > 



Before we get to the final lab of this chapter (a C++ COM client) we need to look at a debugging technique for in-process servers. Recall that by definition, an in-proc server is a DLL that is always hosted by some other EXE. Therefore, when it comes time to debug your DLL servers, you will need to assign some EXE to host your server during the debug cycle.

Assume you have created a COM-based DLL. Also assume you have additionally created a COM-based client that is making use of the coclasses contained in the server. Once each project has been compiled, load the server project into Visual Studio and begin a debug session (F5). This will launch a small dialog box (Figure 3-24). Use the browse button to navigate to the location of the client project. For example, if we are interested in debugging the CoText server seen earlier in this chapter, navigate to the client EXE:

click to expand
Figure 3-24: Specifying a COM DLL debugging host.

Once this association is made, any breakpoints will be triggered by the hosting COM client logic.

If you ever wish to change the hosting EXE, you can change the initial settings using the Project Settings dialog box. Select the Debug tab and edit the Executable for Debug Session edit box.

Note 

The hosting EXE client does not need to be of the C++ variety. Recall that one of the great boons of COM development is its language-independent nature. In the next chapter you will learn how to create Visual Basic and Java/COM clients. This same debugging technique may be used to troubleshoot your COM-based DLLs using a COM client developed in any COM-aware language.

Lab 3-3: Developing a COM Client

In this lab we will be building an official COM client to use the CoCar COM server you created in Lab 3-2. You will make requests of SCM using the COM library, manage interface pointers, work with BSTRs, and exercise class factories. Once this lab is complete you will have ported your humble CoCar through the following iterations over the course of three chapters:

  • A struct in C operated on by a set of global functions.

  • A simple object in C++.

  • A C++ object with multiple interfaces.

  • A binary COM-based DLL.

 On the CD   The solution for this lab can be found on your CD-ROM under:
Labs\Chapter 03\CoCarClient

Step One: Prepare the Project Workspace

Begin by creating a new Win32 Console Application named CoCarClient. This time select simple project. You will already see an empty main() loop provided for you. Before we can use our CarInProcServer.dll, we need to bring in the following files to the client workspace:

  • iid.h and iid.cpp: We need the GUID constants to code against. Insert the CPP file into your project.

  • interfaces.h: We need the interface names to define pointer variables to them.

Include the header files at the top of your cocarclient.cpp file:

// Once you have copied these files to your project sub directory, you are ready to code // the client itself. #include "interfaces.h" #include "iid.h" #include <iostream.h> int main() {      return 0; }

Step Two: Implement the main() Function

To pull together all your COM knowledge, add the following functionality to main():

// Your C++ client code. int main(void) {      // Initialize the COM sub system.      // Grab the IClassFactory pointer from CoCarClassFactory.      // Call CreateInstance() from pICF, and ask for IID_ICreateCar from the CoCar.      // Exercise ICreateCar.      // Next ask for IID_IStats from your ICreateCar or IUnknown pointer.      // Call DisplayStats() from pIStats.      // QI for IEngine      // Rev that engine until the engine block snaps in two!      // Using pIStats->GetPetName(), print the BSTR to the console to inform the user      // of the car's demise.      // Release all acquired interface pointers.      // Terminate the COM sub system.      return 0; } 

Figure 3-25 shows the client output:

click to expand
Figure 3-25: Who says you can't get satisfaction?

Much of this client code will be the same as your CoCarApp application (Lab 3-1). Here is the complete code listing:

// The COM client logic. int main() {      CoInitialize(NULL);           HRESULT hr;      IClassFactory* pCF = NULL;       ICreateCar* pICreateCar = NULL;      IStats* pStats = NULL;      IEngine* pEngine = NULL;      cout << "*********************************" << endl;      cout << "The Amazing CoCar Client" << endl;      cout << "*********************************" << endl;      // Get the class factory pointer of CoCar.      hr = CoGetClassObject(CLSID_CoCar, CLSCTX_INPROC_SERVER,                          NULL, IID_IClassFactory, (void**)&pCF);      // Make a CoCar & get ICreateCar.      hr = pCF->CreateInstance(NULL, IID_ICreateCar, (void**)&pICreateCar);      pCF->Release();      if(SUCCEEDED(hr)){           pICreateCar->SetMaxSpeed(30);           BSTR petName = SysAllocString(L"Shazzam!");           pICreateCar->SetPetName(petName);           SysFreeString(petName);           // Now get IStats           hr = pICreateCar->QueryInterface(IID_IStats, (void**)&pStats);           pICreateCar->Release();      }      if(SUCCEEDED(hr)){     // Show stats and get IEngine.           pStats->DisplayStats();           hr = pStats->QueryInterface(IID_IEngine, (void**)&pEngine);      }      // Zoom!      if(SUCCEEDED(hr))      {           int curSp = 0;           int maxSp = 0;                     pEngine->GetMaxSpeed(&maxSp);           do{                pEngine->SpeedUp();                pEngine->GetCurSpeed(&curSp);                cout << "Speed is: " << curSp << endl;           }while(curSp <= maxSp);           // Convert BSTR to char array.           char buff[80];           BSTR bstr;           pStats->GetPetName(&bstr);           WideCharToMultiByte(CP_ACP, NULL, bstr, -1, buff, 80, NULL, NULL);           cout << buff << " has blown up! Lead Foot!" << endl << endl;           // Final clean up.           SysFreeString(bstr);           if(pEngine)                pEngine->Release();           if(pStats)                pStats->Release();      }      CoUninitialize();      return 0; } 

With this, the COM CoCar server is complete. What we do not yet have is a way for other languages to access the functionality of our server. You could develop an MFC test client to use your current CoCar server, but again, MFC is still using the C++ programming language. How can other COM-aware languages such as Visual Basic and Java make use of CoCar? That is a job for type information, which is the subject of the next chapter.



 < Free Open Study > 



Developer's Workshop to COM and ATL 3.0
Developers Workshop to COM and ATL 3.0
ISBN: 1556227043
EAN: 2147483647
Year: 2000
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net