|
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Features Do you COM? Dealing with Legacy Projects
".NET 3.0 ... high tech and still unexplored in its entirety"
By: Catalin Sandu
Jul. 28, 2007 05:30 PM
You might be tempted to say that once you enter the .NET world, you'll never look back. Nothing seems too easy for you at this moment, what with the brand-new .NET 3.0 that's just out, high tech and still unexplored in its entirety.
Why would a programmer do that? For one, there are those old legacy projects your customers like to use, and nothing can convince them (yet, you hope) to upgrade to the latest and fastest platform out there, thank you very much. Or if you're among those lucky few whose clients are always eager to take the extra step and keep up with the latest technologies, maybe you still have some in-house projects (Visual Basic 6, anyone?) that are too complicated and would take a lot of time and money to convert to your platform of choice. An elegant solution to these problems is to expose your constructs as Component Object Model (COM) objects that can be used without any problem from any Win32 program that can play with COM. The .NET platform allows you to do just that via a fancy intermediate object called COM Callable Wrapper, or CCW, that sits between the COM client and your managed code. More on this later. This article will describe what it takes to expose .NET components as COM objects. You'll find that the job is not so difficult; in fact, most of the time what you'll do is play with some new attributes that would decorate your classes, class members, and methods. You'll even learn how to create an ActiveX control in .NET, something that's still hot off Microsoft's hands. But until then, let's start with...
The Basics
public class HelloClass { Before modifying this class for COM, I need to do a quick detour and explain some of the theories involved in exposing a .NET class to a COM client. The framework component that is of help here is called COM Callable Wrapper (CCW). This is the middleman that stays between your .NET component and the actual consumer. Every call to your class will pass through this proxy, which will take care of the usual COM behaviors for you, like reference counting. When the reference count reaches zero, the .NET object becomes a good candidate for the next round of the framework garbage-collection process. One more thing about CCW: unlike normal .NET objects, the CCW is allocated from an uncollected heap. This is, in fact, the reason why the wrapper can be used from COM clients in the first place. The CCW object is created on the fly, making everything transparent for you, the .NET class designer. Coming back to our hello-there class, the first step in the COM-.NET dance is to mark your assembly as being COM visible. For this, you need to go to the AssemblyInfo.cs file for your project (assuming you're writing a C# solution) and change the ComVisible attribute from false (the default) to true, like this: [assembly: ComVisible(true)] The effect is that everything that's written in the .NET project will be exposed to the COM world. Well, at least this is the short answer; the real story will get revealed in a moment. The same thing can be accomplished if you go to your project's properties, select the Application section, and then click on the "Assembly Information" button. The last option in the dialog box that appears is "Make assembly COM-visible," and checking it will take care of changing the ComVisible attribute to true. Still, ComVisible has other interesting uses as well, which you need to understand if you have to master the COM game as seen from a .NET vantage point. What's the point of getting everything for free if you don't get your feet wet, right? Once you mark an assembly as being COM-visible, everything inside can be accessed by COM clients for free, but this is only partly true. What will actually get exposed is the stuff in the assembly that's public. That's right; all that's private, protected, or internal won't see the COM light, ever. In our hello-there sample, the private data member _name is not exposed at all. The same is true about all static methods and fields from your constructs. The list of things that won't be accessible includes abstract classes, too. What's more, your public data members will become properties for the new COM object. Did I mention that all types that really need to be exposed should have a default constructor? The ComVisible attribute, which can be used on every possible level (assembly, class, structure, fields, methods, so on), comes in handy when deciding which public parts of your library will get exposed. When using ComVisible(false) on a public method, for example, it won't be visible from COM clients. However, you can still use it from other .NET applications. Now that you know how to play nice with COM, all that remains to be done is to... yes, you guessed it - register the resulting assembly in the Windows Registry, so that other applications know about it and use it. The next stop will be...
The Registration Story: The .NET Way Enter the RegAsm.exe command line tool - or the Assembly Registration Tool. This small application will take a .NET component, read its metadata, determine what constructs (classes, structures, so on) are marked as COM-visible, and write the necessary entries in the registry. This friendly tool is smart enough to do a little bit more than that, such as generating a type library for the exposed component, or creating a registry script containing the registration details. Neat, isn't it? You might want to play with the tool to see what other options are available. Assuming that our hello component compiles to a Hello.dll library, here's how you can register it: RegAsm.exe Hello.dll Reader Feedback: Page 1 of 1
Latest Cloud Developer Stories
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week
Breaking Cloud Computing News
|
|||||||||||||||||||||||||||||||||||||||||||||||||