Use of MFC in a COM server - what are my options? - com

Visual C++. I have to implement some drawing and printing functionality that will be incorporated into (other developers') COM dll. Firstly I thought of doing everything using pure GDI and nothing more, but it seems that printing and print previewing is hell of a job to be done in GDI compared to the MFC implementation. So I decided to focus on MFC. Quick side question here: Is my choice right? I mean, are any easy ways of implementing printing (and print-preview) without MFC?
Now that I need MFC (assuming if you also agree with this), I have two questions about how to do it:
1) I believe the COM dll is the ATL project (it's not my code, some other developers independently develop it). Can I enable MFC support in that dll? What are the risks/limitations/drawbacks of having MFC runtime in the COM server? And if you advice doing this, how can I do it?
2) As much as I want to affect the third-party COM server's code as little as possible, I thought it might be the better approach to implement my code as a separate MFC-based DLL, and load and use that DLL from COM server. Do you advice doing this? What are the risks/limitations/drawbacks in this situation?
Shortly, I want to use MFC's drawing and especially printing capabilities in my code, which itself should be integrated in another developers' COM dll (which itself is utilized in a large corporate application). I'm no expert in COM technology so I'm a little bit confused. What are my best options?

You can use MFC in your own dll internally, and expose functionality to your users with non MFC intruded function: for example if you need to pass a point from/to ypur caller, use the GDI standard POINT structure, then convert it to a CPoint to use internally. In this case you don't need to enamble use of MFC in the ATL project ( that is possible anyway ) but of course you need to distribute or link with the MFC dll. If you want mantain the caller com dll as clean as possible, you can definitely create your own ATL+MFC dll and expose your functions via com interfaces too, but keep in mynd to avoid put MFC related objects in the interface.

Printing and print preview is a hell of a job unless you're using MFC Document/View Architecture. Will your COM expose such advanced UI?
If your COM must be independent of .NET then MFC is the way to go, otherwise I would use .NET. If you choose MFC, make sure you link to it statically. Otherwise you will most likely end up with runtime errors on machines where the necessary MFC version is missing.
Except for this, I wouldn't worry about compatibility since the idea of COM is to let the underlying magic do the marshaling of integers, strings and other objects.

Related

Do COM or CORBA bring forward compatibility of compiler or of standard library?

This question follows the previous one below:
Easy way to guarantee binary compatibility for C++ library, C linkage?
I wondered if making interface functions of C++ DLL or shared library with C linkage brings forward compatibility of Compiler and of standard library.
extern "C" someAPI();
The most voted answer was saying that I am wrong. The answer recommended making it open-source. And never mentioned about COM or CORBA. Making it open-source is not always possible.
But recently I am reading books about Windows COM. And I think COM maybe brings the compatibility I wanted. And there is another thing CORBA.
So I wonder if these things, COM and CORBA, really brings forward compatibity of compiler and standard library?
I think network library ACE uses CORBA. And that is only one I know about CORBA.
Isn't CORBA popular nowadays?
What about COM? ActiveX is maybe disappearing but WDF(Windows Driver Foundation) depends on COM.
Thank you very much!
Yes, COM was created, among other reasons, to overcome source code (and .obj, static lib, etc.) reuse issues, whether that source is C/C++ or anything else.
The essence of COM (v-table layout + IUnknown, forget about registration, OLE, Automation, marshaling, and other additional stuff) is very simple (in fact, it's hard to make it more simple). Since it only relies on binary contracts, you can write COM client and/or server code using any language (and any platform, but in reality, only Windows uses it). So you can have a 32-bit COM client written in python talk to a 64-bit COM server written in C++ for example (well, this example in fact requires some cross process marshaling, so it's not pure lightweight COM).
COM is very far from being dead or disappearing (because it's, again, quite simple). "ActiveX" was a marketing / tech mix name, but it's basically COM, and is massively used in Windows, by Windows and 3rd parties.
COM over the physical network (DCOM) is indeed disappearing (in favor of other technologies, like Web, sockets, HTTP, REST, or in general technologies more simple than COM), and what's still used today is basically in-process and out-process COM (out-process is somehow DCOM on the same machine).
I know that CORBA was once upon a time a strong COM competitor (especially because it was available on multiple platforms, including Windows), but it seems to be seriously declining, also in favor of the same more simple technologies (web, etc.).

Create VB6 application using a class in a DLL, then swap out that DLL after build?

so my question is relatively simple, can I create VB6 application that references a class in a dll, and then substitute that dll for another at runtime?
Now my intial guess is... no chance in VB6.
So my thoughts turned to a VB.net interop dll. Could I do it in here, and then call the interop dll from the VB?
Again, my guess would be no.... but I'd be happy if someone knew differently.
The only thing that I think would actually work would be DI in .Net, but I'm limited to .net 2, or 3.5 at a big push, so I dont know if that is possible.
So for the background....
I have a dll that a specific site uses, but we dont want to ship that out to everyone. Instead, we want to build a clone dll which just has the interfaces setup so that the VB6 build will complete.
When it gets to the site that needs it, they want to replace the dummy dll, and drop in their version instead.
Note: We do use RegFreeCOM when its gets installed, so I do have the manifest files that I could play around with if needed.
Any ideas would be much appreciated.
Nick
Its a COM dll so its not statically linked to the VB6 exe, so long as the clsids and interface ids are the same in the type library for both DLLs, you can swap them around as you see fit. (If its a VB6 dll this is trivial to do with the 'binary compatibility' build option)
You could also use late binding instead and instead of making a reference directly in your VB6 code, you would create an object and then set that object to an instance.
Examples and information:
MVPS
Microsoft

.NET out-of-process COM objects sharing static instances in API calls

It's hard to explain our situaction.
We have a 3-tier application. The engine is a DLL coded in C++, then we have a VB6 ActiveX EXE that access to the engine via API calls, and at the top level we have a Excel Addin (in C# using VSTO framework) calling the middle layer with an interop DLL. At this time, each "connection" from the Addin to the engine creates a new EXE (VB6 uses API calls to access to the engine) and all works fine.
Now we are moving the middle layer to .NET, it works 'presumably' fine (it pass all our Unit test) but, we found an error when we open 2 "connections" at same time (ups, no unit test check this situation because it's a new behavour). The DLL have static objects that it's shared over all instances in the same process and we have interactions between "connections". In our old version each "connection" creates a new EXE with no memory sharing between processes, now it's the same process and they share memory and the static objects.
Following the tips from this question. We tried to build a COM EXE in C# to do an out-of-process objects in the middle layer but we have the same result. They share the static objects, at the end, each connection not creates a independent process.
It's clear, but not affordable at this time, moving API calls to ATL or changing the static objects to instanciable references with a handle and change all the API calls to get/set this handlers. I reviewed all examples in MS All-in-one but I didn't find any solution. Neither it's possible to keep only one connection at time, each workbook can have one connection and in the future we want to explore a Web application with multiple connections at same time.
Any suggestion?
Thanks in advance,
Whether COM starts new EXE per each COM object, or uses single EXE to instantiate all the object is controlled by flags parameters passed to CoRegisterClassObject. See
http://msdn.microsoft.com/en-us/library/ms693407(v=vs.85).aspx, and
http://msdn.microsoft.com/en-us/library/ms679697(v=vs.85).aspx
You need to pass REGCLS_SINGLEUSE or REGCLS_MULTI_SEPARATE flags.
Now, the trick is to pass this flag, as you might not call this method directly - the details depend on how you implemented the COM EXE.
it's not clear from the question, but it sounds like the "middle layer" you have was built as a VB6 EXE, and you're trying to replace it with a .net DLL. If that's the case, you'll definitely get the behavior you describe.
With a VB6 EXE com project, instantiating a new object starts a new process. With a .net dll (or a Vb6 dll really) you +won't+ get a new process.
You'd either need to create a .net EXE that exposes COM objects just like your VB6 exe does, or (sounds like you've already investigated this) you'll need to refactor your EXE objects to properly handle multiple instances within a single process.
Honestly, it'd probably be better to do that latter, since relying on singletons like this is generally a bad code smell. But it a pinch, you should be able to replicate the behavior of the VB6 exe with a .net project. You just can't do it in a dll.
Was your middle layer created in .Net? If it was, you might be facing the issue that your COM class is been created as a native .net object instead of a COM object. The solution usually involve using Primary Interop Assemblies. Take a look on this SO question to see if it matches your problem.

What is XPCOM? XPCOM vs COM?

I have trouble understanding XPCOM. How is it different from COM? What makes it cross platform?
Is it a framework with a set of libraries that you can use to do some jobs?
Also, does Component Object Model means every functionality is implemented in component so we can use it without knowing the detail implementation?
Can you someone help me understand this please?
Thanks,
Chan.
I have trouble understanding XPCOM.
How is it different from COM?
XPCOM is Mozilla's own, cross-platform (hence the XP bit) version of COM.
What makes it cross platform?
It is implemented in a library that has been ported to many platforms by contributors to the Mozilla open-source project. You can build it or download a binary for any platform that you wish and, in the extremely remote possibility that you want to use it on a platform that is not already supported, it should be straightforward to port it yourself.
Also, does Component Object Model
means every functionality is
implemented in component so we can use
it without knowing the detail
implementation?
Yes, spot on. The idea is for a language-independent framework that enables different components to communicate and interact, without requiring any special knowledge of the language that any particular component is implemented in. So javascript code can call C++ code, for instance.
This is achieved by components publishing well-defined interfaces, using a language called IDL (or, in XPCOM's case, XPIDL). These interfaces make use of well-defined types with mappings in each of the supporting languages. Every interface inherits from a common base interface, which provides standard methods for reference-counting and type-inference (called IUnknown in COM and nsISupports in XPCOM).
Can you someone help me understand
this please?
In terms of online resources, there are dedicated areas on both the MSDN (for COM) and the MDC (for XPCOM). If you want to really understand the motivation for COM and why it is the way it is, I recommend picking up Don Box's Essential COM. And of course, if you have any specific questions that need answering, you can always come here to ask them. :)

MFC COM or ATL COM (ActiveX)

I have some MFC code (custom CWnd controls and some classes to expose) that I need to make into an activex / COM object with interfaces. Is it easier to make an ATL project with MFC support and make my ActiveX that way or make an MFC ActiveX control?
When doing an activeX control, is doing dual interfaces (like that explained in ACDual from microsoft) good/bad/makes no difference?
MFC is an easier route if you're a newbie in COM stuff: The wizards are better and more helpful. But it's far less flexible than ATL, which is probably not an issue if you simply have a couple of simpole interfaces to implement.
Also, IIRC MFC doesn't support dual interfaces. Dual interfaces are interesting in 2 cases:
- Performance is an issue. Such as a call to a short method executed millions of times.
- The object users are programmed in C++. Calling a native interface is way easier in C++ than calling an automation interface.
In conclusion, dual interfaces are cool but they are really interesting only if you can have them for free. Which means you use a framework which supports them. If you plan on much COM-based work, it's interesting to investigate in ATL and deeper COM knowledge. If you just have to provide a couple of simple MFC-based objects, just stick to MFC.
It's a bit of pain to use MFC for COM - there is too much code to write, macros to copy -
however you have to know what you're doing if you are mixing MFC and ATL because they are deceptively similar yet different, especially if you create windows with ATL.
The main thing is, if you use MFC from an ATL, you will need to start every one of your ATL method with AFX_MANAGE_STATE(AfxGetStaticModuleState( )), otherwise you will get random problems. This is done for you automatically when you implement COM with MFC, which is why there are these ugly METHOD_MANAGE_STATE macros in every method.
Beyond this, it just works. MFC objects inside a ATL objects is what I do..
I've always used straight ATL with no MFC for development of COM components. MFC is useful as an application framework, which I generally didn't need for lightweight (non-UI) COM components. ATL provides lots of support for strings, collections, and various utility classes without the need to bring in all of MFC with the logistical complexities that arise from doing that (like setting context on every public API call, etc). It also includes some basic UI support via CWindow and its friends if you're building a UI component.