I have an ATL COM service which I can connect to via my Windows Forms Application .NET4 application, written for the most part in managed c++.
I can successfully retrieve a pointer to the interface (via CoCreateInstance()), but run into issues when attempting to implement an event sink. I wish to create an unmanaged c++ class in the application which implements an interface defined by the COM server, and receive events from the ConnectionPoint. What I've got so far:
Realising this isn't possible using a managed (ref class) c++ class, I'm using a normal unmanaged class.
Not being able to use any ATL macros, I need to implement the IUnknown abstract functions (AddRef, Release, QueryInterface etc) in the sink class.
I can retrieve the IConnectionPoint pointer for the interface, but the call to Advise() returns E_NOTIMPL. This leads me to believe that i've missed implementing some ATL base functionality somewhere, but I'm not sure where to start.
As an aside, i've found very little resources on the net about using COM in a managed c++ project. The closest i've come to is this article. Does anybody have any good reading on this subject? It's mangling my brain at the moment.
In your managed C++ application add a reference to the COM server using "Add reference" option, this will create a managed wrapper (assembly) for your COM component which you will be able to consume in your "managed c++ code". The events in your COM component should be available as .NET events which can be handled using regular event handling in managed C++.
From your description it seems that you are trying to consume the COM component in your managed C++ application using unmanaged code, which is making things complicated. Mixing managed and unmanaged code should have clear boundaries and jumping too much in and out of these boundaries will make things complex and will lead to other serious issues. Hence I suggest you to consume the COM component using "managed code" (c++) only bu creating the managed wrapper for the COM component.
Related
I am trying to use the COM system for VCProjectEngine. It is pretty simple to use in C# but I am hitting a wall in native C++.
I am using the COM system and so far I was able to get a pointer to the VCProjectEngine interface using the CoCreateInstance function.
But now what should I do with this interface? I would like to access the VCProject interface to be able to add files to the project. I tried to go with LoadProject or CreateProject but it takes a IDispatch parameter not a VCProject one.
Can someone help me with that?
Calling COM interfaces from C++ can be done in a number of different ways:
"low-level" COM calls using CoCreateInstance and the IUnkown interface
ATL (Active-X Template Library) which provides a number of smart pointers and utility functions to make the job a lot easier. Use in conjuction with #import to generate wrapper classes for you.
For Windows Store Apps you should use C++/Cx or WRL (Windows Runtime C++ Template Library)
There are many good tutorials and code samples on MSDN.
Hi we have a c++ project (library) which has to exposed to .net languages or may be other languages (old vb for example but this is not very important). Two options are write COM wrapper for the project or managed c++ wrapper. Which one to choose?
One great advantage, for example, of using manged c++ is using .net collections classes to pass as a parameters instead of enormous complexity of collections in COM.
The term "COM wrapper" doesn't make much sense. If want to create a COM class, there's no reason why you should first create a vanilla C++ class and then create a COM class that wraps it and mimics it. That's one advantage of COM over managed C++: in managed C++, you DO have to create a vanilla C++ class (for unmanaged clients, unless you don't have any) and a managed wrapper class for it (for managed clients).
In my opinion, the deciding factors for when you should use COM or managed C++ for interop are easy:
Use COM if you want to create a completely new unmanaged class (not a wrapper) that can be consumed by clients in any language.
Use managed C++ if want to create a completely new class (not a wrapper) in which you mix a lot of managed and unmanaged code.
So you see, the word "wrapper" shouldn't come up anywhere in your design. Wrappers suck :)
If you're COM collections are enormously complex, you may want to rethink how you approach COM collection management. Totally different issue there, but that being said...
Your mention of old-VB not being very important is more critical to your answer than you may think. Old VB doesn't speak .NET, but it does speak COM very well. If you foresee having to go that road, that is a major push to the COM side.
I'm not a fan-per'se of managed C++ only because it is about the most non-portable, hard-to-manage, hard to read dialect of the language you'll likely ever encounter. However, if the core code in your library is simple enough, you could probably get it up and running in managed C++ with reasonable effort. The more dynamic the library is, the harder it will be to port to .NET management. However...
Once it is there, a COM wrapper can get you back to your COM clients like legacy VB without too many problems provided you took wise choices when doing the port and kept things easily wrappable along the way.
Thats about the most round-about way I can say (with great pain) managed C++ is likely your best option, but I would seriously gel on it before throwing down that gauntlet.
I have followed the steps here to create a COM DLL in Visual Studio 2008. My objective is to wrap an existing unmanaged C++ .lib.
Is there an easy way to implement the COM interface for the lib. Or do I just have to keep adding ATL simple objects which essentially wrap the objects in my library?
For example, I have added the simple ATL object, CMyObject to my COM library, am I to create wrapper code including function members etc in CMyObject that essentially wrap the behavior of MyObject contained in the unmanaged C++ library?
In order to expose your functionality to COM you'll need to perform two major steps:
introduce COM interfaces
implement those interfaces using functionality of code you already have
So yes, the scenario you described is the typical way to solve this problem.
Using ATL will simplify things a lot. However you have to take care of exceptions as well. Since your code is in C++ it can throw exceptions. COM doesn't allow propagating exceptions outside COM methods - if the client is not in C++ it will crash once exception is thrown from your code. So your wrapper layer needs to have try-catch for every method directly called from COM.
I think adding wrappers the way you describe is the best way to go. Given that parameter types for OLE will be different to the C++ parameters in many cases, e.g. BSTR rather than string or char*, some wrapping is required for COM. The only alternative is to have a non-COM DLL.
I want to use WPF in an app. I want to write it in C++. Does the application have to be managed? I know that I can mix managed with unmanaged. I'm wondering if I can have the whole application be unmanaged.
You can easily develop 99% of your WPF application in unmanaged code, but making it 100% unmanaged is quite difficult.
WPF classes don't have a Guid attribute, so they won't work with COM. So constructing WPF objects such as Button and Window with 100% unmanaged code requires one of the unmanaged CLR APIs. The Hosting API is probably the easiest, but it is still quite a bit of work.
If you are willing to accept 99% unmanaged code, just compile your application with the /clr option and use IJW to instantiate WPF objects and call methods like Application.LoadComponent.
Also note that WPF binding to unmanaged objects requires that those objects fully support COM including IDispatch.
As you already know, you can mix managed and unmanaged via interop; however, WPF runs on the CLR.
Here is an article on the Web where some folks speculate about a future unmanaged version:
http://neilmosafi.blogspot.com/2008/07/unmanaged-version-of-wpf-coming.html
Here is an additional reference on WPF/native interop, should you choose to go that route:
http://msdn.microsoft.com/en-us/library/ms742522.aspx
Some classic Windows/C++ applications can't easily be moved to managed C++.net, due to use of external libraries. Is it feasible to use newer GUI libraries like winforms (or even WPF) with such applications, 'dropping in' new controls to replace stale-looking MFC?
Or is it not really worth it, and would take a lot of time?
I've found that C++/CLI is very capable. Are you actually running into problems? It should be able to compile your MFC project directly.
But mixing WinForms and MFC within the same thread could be difficult as they both want to run their own message loop. As Ray Burns has suggested, WPF may be more cooperative with MFC.
Because of IJW it's quite easy to use WinForms or WPF from unmanaged code. More lilkely, though, you'll want to write the new components in managed code and just embed them in your unmanaged application. That means that for all the new stuff you won't have to deal with memory management, etc.
WPF is much more powerful and nicer to use than WinForms, so I would definitely bypass WinForms if you haven't been using it already.
One consideration is you'll want to take advantage of the data binding power of WPF. To do this you'll need to expose your unmanaged data as COM classes or copy the data into managed code. An easy way to do this is to write managed wrapper classes in C++ that access the unmanaged data. Another easy way is to directly access the business object layer (or database) from managed code. It depends on exactly what your current data layer looks like.
A better approach would be to create a new .NET project (C# is your friend) for your UI, and reference your C++ DLLS from there. You're not going to have an easy time mixing managed and unmanaged code in a single project.
See How do I call unmanaged C/C++ code from a C# ASP.NET webpage. It talks about a web page specifically, but the code is identical for a winForms or WPF app.
It's not really worth it, and it would take a huge amount of time.
It's possible to have unmanaged C++ code host the CLR, and to have the managed code run the UI.
But, it's definitely not a trivial task.
An easier approach would be to rewrite the unmanaged code a bit to be invokable via P/Invoke or COM interop, and have a managed app (with winforms) call the unmanaged code.