Classic COM to .NET Interoperability
Building a Managed C++ Client using Late Binding

Gopalan Suresh Raj

Note
To work with any of these samples, you will need the following:
.........................................Microsoft .NET SDK
.........................................Microsoft Visual Studio.NET Beta 2 or higher
 

 

Late binding is implemented by using the Namespace Reflection mechanism. 

1. Create a Visual C++, Managed C++ Application Project

Create a Visual C++, managed Application project. In our sample we use a managed C++ class as the client. To create the client you can use the Visual Studio AppWizard. Choose 'Managed C++ managed Application' as the target, I called the project cppLateBinding, so the main source is called cppLateBinding.cpp.

2. Develop the cppLateBinding.cpp File

Clients that use COM objects should import metadata. In C++ you should use #using directive. The syntax is:

#using "filename"

where filename is the name of the metadata assembly.

Metadata should be accessible at compile time as well as at run time, so for simplicity, lets place QuoteServer.dll in the folder where your client code is located, as well as in the debug and release subfolders. As an alternative you can put the assembly in the folder with the client executable and reference it from source using a relative path.

Add the following line to QuoteClient.cpp file

#using "QuoteServer.dll"

At runtime the program finds the metadata assembly, uses this information to create a Runtime Callable Wrapper (RCW) object that is responsible for:


The RCW itself is a managed object so it is garbage collected. To import the library namespace, you should use the using namespace directive. Add the following line to your code

using namespace SimpleStocks;

Now you can use object the same way you use any managed CLR class.

To import metadata at runtime the Type class from the System namespace is used. The Type class has a static method GetTypeFromProgID("ProgID") that returns a Type object for a COM object based on its ProgID.

To obtain an instance of a COM object we use the static member CreateInstance(Type type) of the Activator class from System namespace. We pass the Type object that we got at the previous step as a parameter.

Now we can call the methods of our COM object using the InvokeMethod member of our Type object.
 

cppLateBinding.cpp
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
// This is the main project file for VC++ application project
// generated using an Application Wizard.

#include "stdafx.h"

#using <mscorlib.dll>
#using "QuoteServer.dll"

using namespace System;
using namespace SimpleStocks;

// This is the entry point for this application
#ifdef _UNICODE
int wmain(int argc, char* argv[])
#else
int main(int argc, char* argv[])
#endif
{
    String *symbol = new String( "iCommware" );
    if (argc > 1) {
      symbol = new String( argv[1] );
    }
    else {
      Console::WriteLine( S"Usage: cppLateBinding <symbol>" );
      Console::Write( S"Assuming Stock symbol is " );
      Console::WriteLine( String::Concat( symbol, " and proceeding..." ) );
    }

    using namespace Reflection;

    // Get Type object for COM server. It uses ProgID of the QuoteServer class.
    Type* type = Type::GetTypeFromProgID("SimpleStocks.QuoteServer");

    // Obtain instance of COM object.
    Object* object = Activator::CreateInstance(type);
    if (0 == object) {
      Console::WriteLine(S"Activator::CreateInstance failed...");
      return -1;
    }

    // Create array of parameters.
    Object* arguments[] = new Object* [1];

    // Set parameter.
    arguments[0] = symbol;

    // Call COM object method by its name.
    // AND copy value to
.NET Developer Platform (NDP) heap
    Object* resultObject = type->InvokeMember("getQuote",
                                                                      BindingFlags::InvokeMethod,
                                                                      Type::DefaultBinder,
                                                                      object,
                                                                      arguments);
  // copy back from NDP heap
  float price = *dynamic_cast< __box float* > ( resultObject );

  Console::Write( "The price of " );
  Console::Write( String::Concat( symbol, " is : US $" ) );
  Console::WriteLine( price );


  return 0;
}

3. Configure your Project Property Pages with the right information

 

 

Identify the folder that contains the QuoteServer.dll Assembly.

 

4. Build the Project Files

------ Rebuild All started: Project: cppLateBinding, Configuration: Debug Win32 ------

Deleting intermediate files and output files for project 'cppLateBinding', configuration 'Debug|Win32'.
Compiling...
stdafx.cpp
Compiling...
AssemblyInfo.cpp
cppLateBinding.cpp
Generating Code...
Linking...

Build log was saved at "file://c:\MyProjects\Cornucopia\ClassicCOM\cppLateBinding\Debug\BuildLog.htm"
cppLateBinding - 0 error(s), 0 warning(s)


---------------------- Done ----------------------

Rebuild All: 1 succeeded, 0 failed, 0 skipped

5. Run the Client

Command Prompt
C:\MyProjects\Cornucopia\ClassicCOM\cppLateBinding\Debug>cppLateBinding
Usage: cppLateBinding <symbol>
Assuming Stock symbol is iCommware and proceeding...
The price of iCommware is : US $186.4

C:\MyProjects\Cornucopia\ClassicCOM\cppLateBinding\Debug>
cppLateBinding MSFT
The price of MSFT is : US $62.8

C:\MyProjects\Cornucopia\ClassicCOM\cppLateBinding\Debug>
cppLateBinding SUNW
The price of SUNW is : US $66.6

C:\MyProjects\Cornucopia\ClassicCOM\cppLateBinding\Debug>

 

Classic COM to .NET Interoperability
Developing a Classic COM Server Component using C# and .NET - The QuoteServer Example
Developing a Classic COM Client Application using Visual Basic ver 6.0 to access the QuoteServer - The VB6Client Example
Developing a Managed C++ Client Application which binds to the Server using Early Binding - The QuoteClient Example
Developing a Managed C++ Client Application which binds to the Server using Late Binding - The cppLateBinding Example

 

Download the entire source code as a zip file.

 

click here to go to
My Advanced C#/.NET Tutorial Page...

About the Author...
Gopalan Suresh Raj is a Software Architect, Developer and an active Author. He has co-authored a number of books including "Professional JMS", "Enterprise Java Computing-Applications and Architecture" and "The Awesome Power of JavaBeans". His expertise spans enterprise component architectures and distributed object computing. Visit him at his Web Cornucopia© site (https://gsraj.tripod.com/) or mail him at gopalan@gmx.net.

 


Go to the Component Engineering Cornucopia page

This site was developed and is maintained by Gopalan Suresh Raj

This page has been visited times since December 27, 2001.

Last Updated : Dec 27, '01

If you have any questions, comments, or problems regarding this site, please write to me I would love to hear from you.


Copyright (c) 1997-2001, Gopalan Suresh Raj - All rights reserved. Terms of use.

All products and companies mentioned at this site are trademarks of their respective owners.