CSE775 - Distributed Objects

Lecture #14 - COM: Introduction to In-Process Components

Web Resources:

Linux Tutorials eclipse Code Project SysInternals Best SysInternals Tools Dr. Dobb's Journal Windows Forms COM at MSDN IDL Language base MIDL types OLE data types IDL attributes MIDL data types MIDL Language Reference

Content:

In this lecture we begin discussing in-process COM components.
  1. Syllabus
    Describes topics to be covered, reading material for you to digest before coming to class, and due dates for the assigned projects.
  2. Project #2, Final Projects
  3. Microsoft Component Object Model (COM):

  4. Building COM Projects:

    Building COM projects is a little more complicated than building console or straight Windows applications. Here are some guidelines:

    • Find all the idl files in the project (most have one, some have two or more), right click on them and select compile. This invokes the MIDL compiler to generate header and implementation files needed for the C++ compiles.
    • Right-click on each COM component project and select rebuild. This includes any proxy projects that are part of the solution. Building ProxyStub code prior to Vista required linking to rpcndr.lib. This is no longer shipped with Vista and Win7, and is not required as one of the other lib files now supplies that functionality. Just remove rpcndr.lib from the linker input properties, and rebuild.
    • Go to the project directory and dir /s *.dll (for In-Proc components) and dir /s *.exe (for Out-of-Proc components). Register each In-Proc component with regsvr32 xxx.dll. Register each Out-of-Proc component by running the EXE with the switch /RegServer. You will find screen shots here that shows how to add regsvr32 to the Visual Studio Tools Menu to do that more easily. To do any registrations within Visual Studio under Win7, you need to run Visual Studio with "run as administrator" option.
    • If the client and component do not share the same context (threading model and security attributes) then you will need to insure that the ProxyStub code is compiled to build the ProxyStub dll, and then register the dll, as above. In some of the workspaces that need ProxyStubs I have provided projects to build them. My recommendation is to build the project without worrying too much about this, but if you get a failure in CoCreateInstance, then look for a ProxyStub that needs building or registering.
    • For C# to COM interop to work correctly you need to set the Platform Target to x86, not any CPU (the default), in the C# project properties on the Build tab. If you don't do that you will get an error message like:

      System.BadImageFormatException: Could not load file or assembly ...
    • You may get cryptic error messages about InitializeCriticalSectionAndSpinCount identifier not found. That is a versioning problem. You need to look into each of the Stdafx.h files in your project and change WINVER 0x0xxx to WINVER 0x0500. Similarly you need to change the _WIN32_WINNT 0x0xxx to _WIN32_WINNT 0x0500, and change any other 0x0xxx to 0x0500.
    • If you are building some of my older projects that I haven't built in a while, you may get a linker error complaining about a missing rpcndr.lib file. That is no longer needed and you can just go to the linker input property on the project property sheet and remove that from the required libraries. It's functionality has been folded into other libraries and the lib file is no longer shipped with Visual Studio.
    • Now you can set the client(s) as startup project(s) and compile and run them.
  5. Build Issues due to Microsoft updates:

    • There is a build issue for .Net / COM interop on 64 bit machines

      You need to set the project build properties to Platform Target: x86.

      There is a build issue caused by Microsoft replacing the typelibrary registration tool

      Now you have to use the tool: C:\Windows\Microsoft.net\Framework64\v4.0.xxxxx\regtlibv12.exe. See Add External Tools.

      There is a build issue caused by a Microsoft Security update:

      The header atlcore.h participates in all project builds that use the ATL library. Microsoft removed a function from this header, apparently for a security update, but did nothing to patch the ATL library to work without it. This problem has been surfacing in the developer community for about a year. I haven't been able to find a Microsoft Patch or KB article about this.

      If you add this function to atlcore.h at the end, just before the end of the namespace you will find that builds work again. You should make a master version of the revised file as Microsoft may do the same thing again in a cumulative update.

      Here's the function:

                      This function is missing after updating in C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\atlcore.h file:
      
      
                      //////////////////////////////////////////////////////////////////////////////
                      // DLL Load Helper
      
                      inline HMODULE AtlLoadSystemLibraryUsingFullPath(_In_z_ const WCHAR *pszLibrary)
                      {
                          WCHAR wszLoadPath[MAX_PATH+1];
                          if (::GetSystemDirectoryW(wszLoadPath, _countof(wszLoadPath)) == 0)
                          {
                              return NULL;
                          }
      
                          if (wszLoadPath[wcslen(wszLoadPath)-1] != L'\\')
                          {
                              if (wcscat_s(wszLoadPath, _countof(wszLoadPath), L"\\") != 0)
                              {
                                  return NULL;
                              }
                          }
      
                          if (wcscat_s(wszLoadPath, _countof(wszLoadPath), pszLibrary) != 0)
                          {
                              return NULL;
                          }
      
                          return(::LoadLibraryW(wszLoadPath));
                      }
      
                      //////////////////////////////////////////////////////////////////////////////
                    

  6. COM Tools:

  7. Details:

    Virtual Function Pointer Table
    You won't understand IUnknown::QueryInterface unless you understand this diagram.

    In-Proc Component code
    We will go over this code, line-by-line.

    Building Raw C++ COM component - detailed notes

    IDL Presentation
    These slides discuss how to describe the structure of a COM interface.

    Interfac Project
    Shows how to pass most common types of data through COM interfaces, e.g., basic types, strings, pointers, and arrays.

    IDL Links