Tomorrow I have planed to do some IDispatch related work, and I will have to create a class that supports this interface.
I have been using ATL classes for a while to create COM objects and manage COM pointers, so I would like to use them for my class as well. But research so far, and discussions with colleagues have led me to believe that I need all the heavyweight IDL stuff even if I want to create a simple class with one property or method.
If that's the case I'll probably resort to writing everything from scratch, but I still hope I'm missing something. Is there a template I've missed?
ATL has an IDispatchImpl class.
Related
I need to extend an old C++ project which uses COM and MFC. I worked with C++/COM before but it was years ago. I see that all COM interfaces implementations in the project inherit CCmdTarget. Even the ones which are not used for UI tasks but just transfer data to methods. Surely CCmdTarget does implement all necessary stuff for COM but it looks like it contains a lot more which is not needed: like wait cursor support and message processing. This is not needed for simple interfaces. Isn't there a more lightweight way to implement them? Or is it a common practice to use CCmdTarget as a base object for all MFC COM implementations?
Sorry if this question seems obvious for everyone, but I am very new to COM. From the tutorial I see here http://www.codeguru.com/cpp/com-tech/activex/tutorials/article.php/c5567, it seems like every COM class created in C++ must implement its own QueryInterface, AddRef and Release. Since these methods should have basically the same implementation for any new class, I don't understand why there isn't some abstract class or whatever that implements it for the developer. I don't understand why I should re-implement the same thing that so many people have already implemented again and again (unless the tutorial is wrong and there IS something).
Thanks
FTA:
"I believe that every programmer who wishes to understand the basic principles behind COM, must write atleast one simple COM object using plain C++ , i.e. without the aid of templates and macros that comes along with MFC/ATL."
To answer your question: Yes, every COM component must implement IUnknown, it's the foundation COM is built on. However, as for the "standard pluming" for creating COM objects this is what the ATL Project Wizard is for.
If you don't want to use ATL or other helper libraries you can use the QISearch helper function that handles QueryInterface for you. AddRef and Release can be implemented in your own base class.
COM needs to work with plain C also so the windows sdk does not really go beyond the definition of the class and its methods.
Yes, every COM class must implement IUnknown, because every COM class inherits from IUnknown - that's one of the basic COM technology principles. This is usually done by using ATL - it has templates and macros for doing that rather easily and even if you don't want to use ATL you can write a template for most trivial cases (like implementing one interface) pretty easily and reuse that.
I've created an MFC control class, which I derived from CWnd.
The control is written from scratch and does not use any child controls. This single class implements all the control logic, including state maintenance, painting, responding to events, etc.
In addition, I need a more "public" interface to be used by the code that uses the control. Ideally, it seems like this would be a simpler class with a much simpler interface. However, having two MFC classes associated with the same Window seems to cause all sorts of problems, or is not even possible.
I'm not really sure the best way to approach this. I'm interested in thoughts on how best to provide a simple interface class to a control like this.
Note that the control is not precompiled into a library or anything. It will be compiled as part of the application.
You might try splitting the class in two, with the more complicated implementation class being a child of the public class.
Ordinarily I'd suggest making a separate pure virtual interface class and using multiple inheritance to connect it to MFC, but I'm guessing you'll want to be able to use the standard CWnd methods on the interface.
The MFC interfaces are simple because they don't actually implement the class, they just wrap the public API (C & WM) to make your coding easier in C++.
For instance you could sendMessage hwnd WM_SetText to the edit field, or use CEdit(hwnd).setText() to do the same.
2 Classes is the go I think,
You could make the interface class the parent of the implementation, or perhaps go for a PIMPL model to join the interface with the implementation.
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.
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:
You write interface only assembly without any implementation and register it.
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.
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.
I have an unmanaged class that I'm trying to dllexport from a managed DLL file. I'm trying to use the unmanaged class in another managed DLL file. However, when I try to do this I get link errors.
I've done this lots of times with unmanaged DLL files, so I know how that works. I know how to use "public ref", etc. in managed classes.
Is there some flag somewhere I need to set? Or do I have to do some DllImport magic?
This is on .NET 2.0 and Visual Studio 2005.
If you want to use an unmanaged class from managed code, you can:
Use some nasty P/Invoke to load the class member functions (constructor, destructor, etc.) and make a nastier managed wrapper class to call the "real" member functions. This gets even worse when there are virtual methods involved.
The second option (which in my opinion is better) is to write a C++/CLI wrapper class (you mentioned that you're familiar with this) that is a simple proxy to the unmanaged class. For every member function you have in the unmanaged class you'll have a similar one in your proxy class. Then it's a simple case of adding a reference to that DLL from your managed project, and you'll be able to use your class as any other .NET class. Take into consideration that you'll run into more work if your class exposes other unmanaged stuff (those that can't be marshalled).
If you need more information on the second option, I could look up some old links that explained this technique more.
You need to use an interop assembly for unmanaged libraries or COM components. Here is a link with good information regarding this.
If it is a COM DLL file then you can use COM .NET interoperability. Stack Overflow question Is there a best practice for accessing C++ native COM functions to interop from C#? is another question which answers this.