Using VCProjectEngine and COM - c++

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.

Related

Using COM Interop to use a DLL

I have to use a DLL in my project that is a .NET assembly. I have to use C++ for this project. I'm a relative beginner to programming, so my knowledge doesn't extend too far. I was told COM Interop is one way to get the DLL to work in my project (the other being C++/CLI). The problem is I have ZERO idea how to begin, as I've never done anything like this before, and the Microsoft documentation on the matter isn't really helping.
If anyone can even point me in the right direction, that would be much obliged.
Here are some good resources to get you started:
Introduction to COM
COM from Scratch (Covers using COM from C++)
MSDN's section on COM
That being said, you'll also need to make sure that your .NET project is setup to expose the classes via COM. Make sure to turn on Register For COM Interop in your project settings, and flag appropriate types with [ComVisible(true)] (Unless you make the entire assembly ComVisible, in which case you would flag types you don't want to expose with [ComVisible(false)])

Interoperability between unmanaged and managed C++ DLL

I currently have an old unmanaged C++ DLL using MFC. This DLL has a bunch of code which is multi-threaded and written back in 2003 using VC6. This code sadly doesn't work anymore.
I've been tasked with finding an alternative way of running this multi-threaded code so that it does function as intended. Someone before me had already rewritten it in C#, and I need to port that C# code over to VC++. I did some research and realized that I could save some time in the porting process by just porting the C# code to VC++ (using the .NET framework). But then I realized that my old MFC DLL cannot run this .NET code.
My idea is to write this multi-threaded code in a VC++ DLL (using the .NET framework) and using some form of interoperability to be able to call the functions from the old DLL to the new DLL.
I have looked into COM interoperability as well as wrapper classes. What is the best way of accomplishing this? Are there any tutorials that could help me with this task? (I've already done some extensive searching and there are a lot of tutorials using unmanaged C++ DLLs to C# DLLs, but not much that pertains to my situtation).
Just so you know, I cannot compile the old DLL with /clr as this DLL is hosted in an old Win32 application as well. Compiling with /clr causes the application to crash, or else this would have already been done.
TO CLARIFY: I'm curious as to why calling functions residing in a C# DLL from an unmanaged C++ DLL through a COM interop seems so simple compared to doing the exact same thing using a managed C++ DLL. I even have a proof-of-concept between C# and C++, but I can't for the life of me begin to understand performing the exact same task with C++. Does there happen to be just a simple tutorial for calling just one simple (let's say 'Add') function from unmanaged C++ to managed C++?
If you have a (managed) DLL, regardless of the language(s) it is written in, you need a process to run it in. If you have a native process that -- for whatever reason -- must not use the CLR, that you cannot directly use a managed DLL (any code that depends on the CLR in-process) from this process directly.
You would need a second helper process that runs the managed DLL and, for example, exposes a COM interface that the native process could call. (out of process COM server)
I have looked into COM interoperability as well as wrapper classes. What is the best way of accomplishing this?
Not sure what you mean with wrapper classes, but an out of process COM server for your managed DLL could do the trick. (Obviously, this is quite some overhand wrt. to managing the proper registration and startup/shutdown of the helper process.)
Breaking the problem up a bit (as far as I understand):
[oldish Win32 app (no! CLR)]
<- normal DLL interface -> [native/MFC DLL (no! CLR)]
<- via COM -> [stuff in a separate executable]
If this is what you are looking for, then this article (just a quick Google hit) may be helpful:
http://www.codeproject.com/KB/COM/BuildCOMServersInDotNet.aspx
For COM in general, I think any COM tutorial should cover what you are supposedly trying to do.

Unmanaged C++ COM and Managed C++ .NET4 interop

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.

Create COM DLL from Unmanaged C++ LIB

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.

Advice on whether to use native C++ DLL or not: PINVOKE & Marshaling?

What's the best way to do this....?
I have some Native C++ code that uses a lot of Win32 calls together with byte buffers (allocated using HeapAlloc). I'd like to extend the code and make a C# GUI...and maybe later use a basic Win32 GUI (for use where there is no .Net and limited MFC support).
(A) I could just re-write the code in C# and use multiple PINVOKEs....but even with the PINVOKES in a separate class, the code looks messy with all the marshaling. I'm also re-writing a lot of code.
(B) I could create a native C++ DLL and use PINVOKE to marshal in the native data structures. I'm assuming I can include the native C++ DLL/LIB in a project using C#?
(C) Create a mixed mode DLL (Native C++ class plus managed ref class). I'm assuming that this would make it easier to use the managed ref class in C#......but is this the case? Will the managed class handle all the marshaling? Can I use this mixed mode DLL on a platform with no .Net (i.e. still access the native C++ unmanaged component) or do I limit myself to .Net only platforms.
One thing that bothers me about each of these options is all the marshalling. Is it better to create a managed data structure (array, string etc.) and pass that to the native C++ class, or, the other way around?
Any ideas on what would be considered best practice...?
UPDATE:
I know I can re-write the native C++ code from scratch, but it means duplicating the code and prevents me from easily reusing any code updates with any Win32 application. What concerns me most is the best way to marshal the various data between the managed and unmanaged world. To me, a mixed mode DLL looks like the most flxible option, but I'd like to get a different perspective on the potential pitfalls.
Why not just use .NET directly? It seems to me like your problem arises from the fact that you are dependent on the original native library, but you don't mention that it can't simply be re-done in .NET.
As for .NET-native interop, PInvoke is messy, but it does work. I'd go with that if you can't change the original DLL into .NET.
Option C gives you the least work if the marshaling turns out to be simple and easy for the framework to handle (is everything blittable?). It also gives you a place to hook in your own marshaling. I wrote something about this ages ago marshaling between date types etc but I think today I would write a marshal_as<> overload between your managed and native types. It would be the most elegant solution and also the least code.
Update: found my old article - it was for PInvoke. http://codeguru.earthweb.com/columns/kate/article.php/c4867/