|
The C# Column
COM Interoperability
COM components and .NET components are not compatible
since they have different internal architectures. However, there are tools available
in the .NET SDK for generating COM proxies for .NET components and .NET proxies
for COM components.
Using
these proxies we can use COM components in .NET projects and .NET components
in non-.NET projects.
Lets now discuss these two situations.
Using COM components in .NET applications
Here we will be using a COM component called AtlServer
that exposes an interface IMath containing two methods Add( ) and
Sub( ). The component is stored in the file AtlServer.dll.
Note that AtlServer.dll must be registered
in you machine. If it is not registered simply build the AtlServer
project so that .NET will make the registration or use the regsvr32
utility.
We now plan to use this COM component in a .NET project.
For this we have created a console application and named it AtlClient.
To use the COM component in our project we will have to create a wrapper class
for the COM component.
A wrapper class surrounds a class that follows a different architecture than
.NET. This class provides a familiar interface to the .NET architecture.
We can create a wrapper class in two ways. The first
is to use the TlbImp.exe tool provided in the .NET SDK. TlbImp stands
for Type Library Importer. This EXE is invoked from the command
prompt as shown below:
c:\com_interop\AtlServer\Debug>tlbimp AtlServer.dll /out:NetAtlServer.dll
The /out option will store the newly created wrapper
class in the NetAtlServer.dll file. We will have to copy NetAtlServer.dll
in the Debug sub-directory of our .NET project.
The second way to create a wrapper class is to right-click
in Solution Explorer and choose the Add Reference option.
Next we must choose the COM tab. On doing so the window shown below
appears.
To select the file, click on the Browse
button, locate the file and select it. On clicking OK, a file with
the same name i.e. AtlServer.dll gets created in the Debug
sub-directory of our project and contains the wrapper class called CMath. We
can now call the methods of the class as shown in the following code.
using System ;
using AtlServer ;
namespace AtlClient
{
class Class1
{
[ STAThread ]
static void Main ( string [ ] args
)
{
CMathClass
m = new CMathClass( ) ;
Console.WriteLine
( m.Add ( 10, 20 ) ) ;
Console.WriteLine
( m.Sub ( 20, 30 ) );
}
}
}
Using .NET components in non-.NET projects
To use a .NET component in a non-.NET project we have
to use a tool called RegAsm, standing for Registry Assembly. This
tool registers a .NET component into the system registry so that standard Windows
clients can bind to the classes in the component.
The .NET component that we have created is just a simple
class library called NetServer that contains the following code.
using System ;
namespace NetServer
{
public interface IMath
{
int Add (
int n1, int n2 ) ;
int Sub (
int n1, int n2 ) ;
}
public class CMath : IMath
{
public int Add (
int n1, int n2 )
{
return
n1 + n2 ;
}
public int Sub ( int n1,
int n2 )
{
return n1
- n2 ;
}
}
}
Here we have declared an interface called IMath and
implemented this interface in the CMath class. On building this project we get
the NetServer.dll file.
Now we need to register this component in the registry
using the RegAsm tool as well as create a corresponding COM type library file
(.tlb file). To create a COM type library file we need to use the TlbExp tool.
TlbExp stands for Type Library Exporter. This tool interrogates
the assemblys manifest and outputs a corresponding COM type library. We
have used both the tools, as shown in the following figure.

Now let us create a non-.NET project that would use
this component. We have created our project in VC++. To create this project,
click on Visual C++ Projects and select Win32 Project.
Name the project as NetClient. On clicking OK
the window shown in the figure above appears.
In the Application Settings tab select the
Console Application option and click on the Finish button.
We need to add the following code to our project.
# include stdafx.h
# include iostream.h
# import C:\dotnet\c#\com-interop\NetServer\
bin\Debug\NetServer.tlb
using namespace NetServer ;
int _tmain ( int argc, _TCHAR* argv [ ] )
{
CoInitialize ( NULL ) ;
IMathPtr p ;
HRESULT hr = p.CreateInstance
(
NetServer.Math ) ;
if ( FAILED ( hr ) )
{
cout << CreateInstance
Failed << endl ;
return 0 ;
}
cout << p -> Add (
10, 20 ) << endl ;
cout << p -> Sub ( 20, 10 ) <<
endl ;
return 0 ;
}
Here we have imported the Type Library using the #import
directive. Then we have created a pointer called IMathPtr.
Using the CreateInstance( ) method we have stored the
component objects address in the interface pointer and then used it to
call the Add( ) and Sub( ) methods.
On executing this program we get the output on the
console.
 |
Yashavant Kanetkar, one of the first Express Computer
columnists, is an established software expert, speaker and author with several
best-sellers to his credit, including titles like “Let Us C” and the “Fundas”
series. Contact him at kanet@nagpur.dot.net.in |
|