tags:

views:

189

answers:

2

I have a pre-existing c++ object model which represents the business layer tier of an application. I want to be able to expose the object model to applications written in other languages i.e vbscript, VB, javascript etc. I believe the best way of doing this is to wrap the business objects with a COM layer.

What fast and effective methods are there for doing this. Any advice, links to practical "How to" documentation would be very much appreciated.

Because I'm starting a bounty on this , here's a few extra guidelines for potential bounty hunters :- 1)I've decided on an ATL approach 2)I'm now specifically looking for links to really good "how to and quickly" documentation on wrapping a pre-existing c++ object model to make it useable by a scripting language like javascript 3) Something with small working examples showing me what code needs to be added to what files, e.g what goes into the cpp , idl and hpp/h etc. It' must include an example I can compile test and change to get a better understanding.

Addendum ..... Further context. For me this is a re-visit to COM after about 10 years. I did MFC and ATL COM for the 3 years prior to 2000. I understand what COM is , the principles used to implement it in C++, threading models etc. Any "how to and quickly" documentation will not be leading me blindly and glazing over important principles, more it'll be a guided re-learning experience.

If I had more time I'd dig into "developer's workshop to COM and ATL 3.0" by Troelsen, a very good book but it's a very slow kick (re)start.

Further context following comments...........

Keeping it as simple as possible , Single-Threaded Apartment model and an inprocess dll.

+2  A: 

http://www.lambdasoft.dk/Comet/index.htm

Comet is language binding between COM and C++. It allows you to do both COM client and COM server programming, without any dependency on either ATL or MFC. In other words Comet is a replacement for ATL.

Kyle Alons
At least put a short description in the answer and not just a link. Besides, latest version is a beta from 2004...
Georg Fritzsche
The beta label is a misnomer. We've been using it in production software for 8 years.
Kyle Alons
Ah, that puts it into perspective. With just the link there it looked a bit like pasting some google result :)
Georg Fritzsche
+3  A: 

I find a good collection of articles for beginner in http://www.codeproject.com/KB/COM/index.aspx?#COM/DCOM/COM+%20-%20Beginners. This are:

http://www.codeproject.com/KB/COM/hellocom.aspx, http://www.codeproject.com/KB/COM/comintro2.aspx, http://www.codeproject.com/KB/COM/comintro.aspx, http://www.codeproject.com/KB/COM/com_server_without_mfc_atl.aspx, http://www.codeproject.com/KB/COM/com_in_c1.aspx

But if you start to program a COM objects it's very important to understand threading models of COM. This is explain very good here

http://www.codeproject.com/KB/COM/CCOMThread.aspx, http://www.codeproject.com/KB/COM/CCOMThread2.aspx

But I decide to answer you because I want suggest to choose a little other modern way. COM technology is very old. Dot NET has all the features inside and will permanently developed. So I find an approach from Building COM Servers in .NET the most interesting. You write your COM full in C# divide the development of your COM objects in two parts:

  1. You write interface only assembly without any implementation and register it.
  2. You develop a .NET classes which implements this COM interface.

You can look at the more easy version of the same in http://www.codeproject.com/KB/COM/COMinDotNet.aspx, http://www.codeproject.com/KB/cs/CreateActiveXDotNet.aspx, http://msdn.microsoft.com/en-us/library/ms973807.aspx, but I recommend you the way "Building COM Servers in .NET" described in http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx.

UPDATED after the comment: Sorry, but you are searching an easy way to solve a complex problem. It is impossible.

It is very important to understand, that despite of quasi similarity there are a lot of principal differences between object oriented C++ and COM. It’s important to understand, that COM isn't an object-oriented language but a binary protocol. A software component (COM objects) is a binary unit of reusable code. It solves a lot of problems existing in separate compilation of modules of programs designed based on object-oriented approach.

If, for example, somebody inherited you classes and you change later some private members, it makes influence to the all inherited classes. The full code used your C++ objects must be recompiled at least because sizeof(object) has been changed. Such problem not exists in COM, because all who use your objects don’t inherit your object classes. One uses your objects through interfaces, which signature and sizeof() will not be changed after you modify some private members of your base classes. You can read online some very good examples in the first chapter of the classic book "Essential COM" by Don Box: http://books.google.co.uk/books?id=kfRWvKSePmAC&dq=essential+com&printsec=frontcover&source=bn&hl=en&sa=X&oi=book_result&resnum=6&ct=result. I recommend you also to read a small article http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/COM/IntroToCOM.htm to understand more differences between COM and C++ objects.

If you rewrite your C++ objects as a COM objects you have to choose threading model, you have to understand how to write a thread safe program or you have to use Single-Threaded Apartment model. All your objects will be exist (allocated and running) in a separate thread. If you choose Out-Of-Process COM object (an exe with all your objects will be created), then a new process will be created. If somebody calls a method of your object a marshaling of all parameters will be done. Marshaling of parameters means allocation of memory in another thread and copying of all parameter to the thread. All this things which I described before are not a terms of C++ objects. I write this only to clear that COM really not the same as C++ object model.

So to wrap your existing C++ objects you have to define some pure virtual classes – interfaces which you implement in your objects. This interface must be in written in IDL/MIDL (Microsoft Interface Definition Language). This is the most important thing! Then you have to implement these interfaces as COM coclasses using your existing C++ classes.

I am sure if you do these work in .NET you have not be required to study a lot of implementation details typically needed to know for COM developer. You just define an Interface in C#/C++ (a pure virtual class) and compile it. You can generate a private key for strong signed assembly inside of Visual Studio. Just go in the project settings in "Signing" part and select "Sign the assembly" then choose "New" strong name key file. It’s all. With this way you full define a COM interface. A MIDL version of the interface will be generated for you.

Then you create a new project in C# or C++ and declare classes which inherit the interface which you define before. During implementing of this interface you can use your entire existing C++ object. So you will be able quickly rich your targets. Just follow the way described in details in http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx. With this way you will not have to study a lot of technical details which you have to know for classical COM implementation in C++. And you will study a modern .NET instead of studying the old and de facto dead (or not further developed) COM.

Sorry for the long answer.

Oleg
Thanks Oleg. I am however looking for something very specific. Your information is very good for learning COM in general, but I need something that will take me through step by step line by line, how to wrap an object model with com. I'm being very lazy about this because I'm hoping something very specific exists and I don't have too long to spend on it. Your advice about using DOT NET doesn't help me at this point, but I will definitely use it in future projects where DOT NET is permitted. +1 for the DOT NET Approach.
Rich
You are out of luck - something very specific does not exist.
TomTom
@Oleg, Excellent summary of considerations using COM. Wish I could upvote you twice. I've added further context to the question following your comments. Thanks.
Rich
@TomTom. Funny you should say that, but that's why I've asked the question. I've been through most of the code resources I know of including all the codeproject.com ones but haven't really found anything along the lines I'm looking for. Maybe I should take the time to write an article once I've been through the learning curve again.
Rich
@Oleg: For the best contribution to the answer, you get the bounty. Many Thanks.
Rich