tags:

views:

190

answers:

4

I'm dealing with the following issue: a (third-party) software (Software A ) we are using extensively allows the programming of what it calls 'extensions' using a Component Object Model (COM) interface (actually several interfaces). It provides the MIDL files for these interfaces as well as a 'project template' for Visual C++ as part of an SDK (IDL files, headers and interfaces are already there, only the implementations for the interface functions are missing). To be comaptible, all extensions have to conform to (i.e. must implement) the given COM interface structure.

However, as my familiarity with C++ is rather limited I was hoping to implement the COM in C# and .NET - on the other hand, the pre-defined interfaces make heavy use of pointers and custom data structures, so I'm wondering if I'm not better off implemementing the interfaces in their native C++ rather than trying to recreate everything in C#.

A little more background maybe: the ultimate goal is to control a piece of custom hardware (via USB) from inside Software A. I have already written a small .NET app wrapping the driver (another third party software) using DLLimport, which was surprisingly painless. In other words, the COM object I am trying to build is essentially a bridge between (third-party) Software A and (third-party) device driver B, which must conform to the interface specifications given by A.


sample MIDL code:

[ id(0x00000004)]
HRESULT GetWaveData([in] BSTR name, [out] IWaveData ** data );
[ id(0x00000005)]
HRESULT GetImageData([in] BSTR name, [out] IImageData ** data, [out] Palette * Palette );
[ id(0x00000006)]
HRESULT SetVariable([in] BSTR name, [in] IVariableData * variable );
+4  A: 

It's not really possible to answer this question without knowing the problem completely. But generally, I would go with the C++ route. By adding CLR to the world, you'll have to deal with interop issues and possibly handle with nasty pointer issues (since the nature of it is dealing with low level hardware related stuff) in C#. As a result, probably, your real choices are an unclean C# source or going with C++. I guess I'd choose the latter.

Mehrdad Afshari
+2  A: 

Technically, you're not implementing the interfaces in C++ but MIDL. It's a separate interface language and it's worth knowing if you're going to do COM work.

Anyway, it's not uncommon to use .NET interops to implement COM objects, but the two are not really compatible technologies. You WILL run into gotchas unless you're writing very simple objects.

To get you started, here's some random assortment of pointers along with a couple of articles that I've used in the past.

  • COM is an interface-driven technology. Repeat that to yourself again and again.
  • Develop the interface definition separately, using MIDL.
  • COM garbage collection is deterministic (reference counting), but this starts to fall apart when used with .NET, where the garbage collection happens automatically and unpredictably.
  • Dealing with Eventsinks/event handlers is ugly.

A small taste of the type of headaches you'll run into: http://www.codeproject.com/KB/cs/LingeringCOMObjects.aspx

More on why you should NOT let Visual Studio auto-generate the COM interface for you: http://blogs.msdn.com/mbend/archive/2007/04/17/classinterfacetype-none-is-my-recommended-option-over-autodispatch-autodual.aspx

Bridging events: http://www.west-wind.com/presentations/dotnetfromVfp/DotNetFromVfp_EventHandling.asp

hythlodayr
+1 Especially for the Eventsinks bullet. This has been a huge issue for me in the past.
Matt Spradley
Thanks for the links! The MIDL definition already exists - that's exactly the issue: how do I translate the MIDL interface definition into .NET, as my understanding is that exposing .NET libaries to COM does not involve MIDL (am I wrong?)Events are luckily not an issue. All the COM does are explicit function calls of the set/get type. So it is probably a fairly simple object.
Andreas F
Exposing .NET libraries to COM doesn't HAVE to involve MIDL, but it's bad practice to let Visual Studio auto-generate the interface definitions for you.In your situation, you're lucky so I think it builds a stronger case for trying out the interop solution.Anyway, the second link I gave you gives you a very small example of how implement an interface using C# so I think you're good to go.
hythlodayr
+1  A: 

You should only use .NET for this purpose if it gives you advantages. For example, we once needed webservices invokation and support for it in .NET is much better, so we went that way. In your case the advantage is that you're more familiar with .NET and that might be worth choosing.

However if you implement the COM object in .NET you will have to require .NET runtime an every machine where the object will have to be used. Plus you may have problems implementing interfaces that have custom types difficult to marshal.

You need to compare the advantage - more familiarity in you case - with the technical burden you encounter - possible deployment and marshalling issues.

My personal opinion is that the .NET path is only to be chosen if one needs functionality readily available there (like webservices invokation).

sharptooth
+1  A: 

It sounds like the decision you're making is one of whether to go for a native application, or a .NET-based application.

You need to think about the following:

  1. Deployment issues: where are you going to deploy this app? Is it something that will run on hundreds of workstations, or just a couple? How much control are you going to have over the machines on which it is installed? Remember that you're going to have to ensure that the correct version of the .NET platform is installed;

  2. Maintenance issues: you're clearly more familiar with .NET, but who is going to look after the application in the long term? Are they going to be expected to be familiar with C++? Native development really is a different kettle of fish from managed development, since "housekeeping" is a very important part of it;

  3. Third party dependencies: it sounds to me like you're trying to use a third party COM library to communicate with your device through USB. However, you've mentioned that you've written a .NET wrapper for the hardware driver--can you elaborate, since this is a little confusing. If possible, and if not too much hassle, don't introduce dependencies;

  4. Resource constraints: if your app is going to be installed "in the wild", what are the constraints re hardware? Programming using an unmanaged environment allows you fine-grained control over how much memory your application will use, and how CPU-intensive it is--this is, of course, a trade-off against having a managed layer take care of that resource management.

In general, if you're developing an application where you don't need to deploy to thousands of users with disparate hardware configurations, I would choose the .NET platform. COM interop on .NET is relatively painless, and programming on a managed platform means that you can concentrate on what is important. If you've never programmed in an unmanaged environment before (C/C++), you're in for a bit of shocker.

Eric Smith
Thanks for the reply! I edited my original question to make things a little clearer. As you correctly suspected, deployment is a non-issue, and neither are resource constraints, so I'd rather avoid getting into unmanaged code.
Andreas F