MFC Dll with COM Interface - c#

I am pretty new to managed/unmanaged interoperability and COM concepts.
I received a suggestion of using COM Interop, for using my existing MFC code in C#. But the problem for me is, i have a MFC Dll which is not a valid COM component. How can I make this MFC DLLs to have COM-accessible interfaces ready for use in .NET?

From thread Loading MFC DLL in C# Windows Application
To access native code from C# you have a few choices.
Most directly, you can use DllImportAttribute to describe your DLL's entry points in C# terms so that they can be called via P/Invoke. They'll look like static methods to your C# program.
Less directly, you can create a Managed C++ assembly that wraps your DLL in one or more managed objects. The Managed C++ DLL can be accessed from C# via Add Reference (because it is a managed assembly with a .dll extension) and should also be able to access your MFC dll by using #include to include the MFC dll's header file.
A third option would be to turn your dll into a COM object so that your C# program can access it that way.

There is no simple way to make MFC Dll COM accessible. It is necessary to write a lot of COM code manually, making COM wrapper. If you don't have previous COM experience, this may be difficult. The second option from Jacob Seleznev's post looks less painful. C++/CLI wrapper which is internally linked to existing MFC dll, and exposes pure .NET interface to C# client, looks like optimal solution.
If MFC Dll exports C-style interface (API), and not classes, use PInvoke.

From my experience, I concur with #Jacob Seleznev and will add that if your MFC DLL interface contains mainly "simple" parameter and return types, using the DLLImportAttribute is most likely going to be your path of least resistance.
A great reference for marshaling types is to see how it's done against the unmanaged Win32 API. That can be found here:
pinvoke.net
What I've done is find an API call with like types and see how that call is setup on pinvoke.net. I don't use it often anymore, but it was extremely helpful a few years ago.
Hope this helps.

Of the three ways to call native code from managed code (COM Interop, P/Invoke, and IJW or C++/CLI interop), COM Interop is the slowest. And if your existing native code is not in the form of a COM component, then it's also the hardest because that will be step 1.
To use P/Invoke you will need some C-style functions (extern C) that go on and call your existing code. To use IJW or C++/CLI interop you will implement a public ref class (in a file compiled /clr) with methods that go on and call your existing code. It is up to you which you find easier. Once you have the wrapper, from C# you can do the PInvoke with a DllImport attribute on the declaration of the functions, and you then call them as usual. To do the IJW you add a reference to the assembly with the public ref class in it and call the methods on that class as usual.
My recommendation is to ask whether you want some sort of Facade pattern where you're putting some logic in front of the interop - if so, go IJW. Also if you want to control the marshaling, go IJW. If not then go P/Invoke. But either way works.

Related

Explicit Linking DLL from C++ Project - (7zip, 7z.dll)

I am trying to use 7zip from within my application code. On 7zip's website, they say I can use 7z.dll. So, I tried to reference it from C#, but that didn't work. So, I decided to write a C++ library that references 7z.dll, and then I can reference that library from C#.
I was able to load the library (I think) in my C++ library, and I am able to reference that library from C# and successfully call a method.
However, I don't know how to figure out the method names inside the 7z.dll library so that I can call them.
Please help
Hmm, Hans Passant pointed out SevenZipSharp which makes my answer rather useless ;-) I'll leave it for purely educational purposes. No need to write your own COM interop wrappers if somebody else has already done it for you...
I had a look at their C++ example (under CPP/7zip/UI/Client7z). Everything is done using COM interfaces and various types of callbacks.
While C# has excellent COM interop support, it would require redeclaring the relevant COM interfaces in C#, or perhaps using late-bound dynamic magic instead. However, both of these options are rather non-trivial for a project the size of 7z, so on second thought it's likely best to stick with your C++/CLI wrapper approach.
Within that example, you can see exactly how main does it: It loads the DLL (using a wrapper class NDLL::CLibrary around the LoadLibrary call), then obtains a pointer to the COM CreateObject function (via the same wrapper that does a GetProcAddress internally).
Once you have the address of the CreateObject function, you can call it with the appropriate application and interface GUIDs to obtain instances of objects that implement them, after which you can use those objects to do the actual work. The interfaces themselves are declared in header files such as IArchive.h.

How to migrate from C++ COM to C++CLI

I have a C++ DLL that exposes stuff via COM. I want to convert it to C++/CLI that exposes a managed interface. Ideally I just add CLI and convert interfaces one by one. So far I haven't succeeded in anything, so I'm looking for a specific strategy.
More detail:
A long time ago, I created an app using COM to communicate back and forth between C# and C++. I'm sick of COM, and the registration and the hoop jumping needed on the C++ side.
I want to use C++/CLI, and get the whole thing working as managed code with the occasional call from C++/CLI to native libraries I'm using.
Can anyone suggest a gentle migration path, such that I can have both CLI and COM going, and convert things over class by class testing as I go? Or something like that.
To be clear: I currently have native C++ code defining and implementing COM interfaces. I have C# code using COM attributes to export classes. All this stuff gets registered for COM interop, and there are calls in both directions. I hope to switch the C++ to CLI and switch to managed classes in C++ rather than COM classes.
Question updated for Ramhound: Anyway, I'm running into brick walls. Turning on /clr on a C++ dll gives me link errors from other stuff trying to connect to that C++ code. (Unreadable ATL/COM messages of the sort that drive me away from C++)
You may want to read through this, as it provides some different approaches and considerations involved: http://msdn.microsoft.com/en-us/magazine/dd315414.aspx
Here is a simple example of how to use interop in C++/CLI, where you could define a method or two and add more as you go: https://learn.microsoft.com/en-us/archive/blogs/borisj/interop-101-part-1
please follow this
http://msdn.microsoft.com/en-us/magazine/cc163494.aspx
use tlimp to generate a COM unmanaged DLL to a managed DLL
is pretty simple!!!

How to use a C++ library in a C# app?

Thus far I've figured out out I needed to recompile the library as a .dll instead of a .lib, enable /clr and /EHa instead of /EHsc. Now I've got a managed dll which I've added as a reference in my C# project.
Now how do I use it?
I'm prepared to write some wrappers, but I don't know where to begin or how to "see" what functions I've gained access to. I've read a little bit about how the class names and functions might be mangled by the compiler... do I need to go back and add __declspec exports everywhere (if so, how?), or is there an option in VS2010 that says "don't mangle it!"?
The C++ library in question is still under active development, so I'm hoping I can modify the C++ library as little as possible and just recompile it periodically with a few switches, and then expose the new functionality as I need it.
If you are going to compile your C++ (if originally was unmanaged C++) you will need to do much more than just add the /clr switch. In order for C# to use the DLL you will need to create managed classes and other types based on CTS which are compatible with C# (.NET).
See and ref classes.
A good book to read about the subject (IMHO) is this one
You can either expose the functions as C style functions (i.e., no mangling) from your dll or you can expose them as COM objects.
I'd suggest writing a COM wrapper, and using that instead. Have a look at http://msdn.microsoft.com/en-us/library/035x3kbh%28v=VS.80%29.aspx for intro instructions. You'll want to make your object interfaces derived from IDispatch and be automation compatible, which should enable the runtime to consume them without any custom marshaling.
A nice benefit of this approach is you can continue to build your native code as a library, and just make your COM project use it. Also, it's still native code inside the COM object, so there's much less potential for unknown problems (once you get the interface layer working).
That's my suggestion, anyway.
Yes, wrap it in à COM object. I believe ATL is what you meed to do this with the least effort.

Sharing objects between C# and C++ code

Is it possible to share references to C# objects between C# and C++ code without massive complexity? Or is this generally considered a bad idea?
The best solution for sharing a C# object between native and managed code is to use COM interop. This allows you to essentially share an interface of an object between managed code and it's equivalent signature in C++.
As for the complexity side of things. The majority of COM interop scenarios are straight forward and really are no more complex than good old COM programming. On the managed side it looks really no different than a normal interface.
Once you introduce multiple threads or start playing around between COM apartments though, things can get a bit tricky.
In my experience, the easiest way to get this working is the following.
Define an interface in C# that you wish to use in C++
Mark the interface with the ComVisible(true) attrbute
Run tlbexp on the assembly which generates a TLB file
Import the TLB into your native project
This will get the interface definition into both of your projects. How to pass that between the projects requires a bit more detail into your architecture.
Another solution I can recommend, from personal experience, is to use a managed C++ interface between the two if the C++ code you want to access is too large or too complex.
For example, I am using the RakNet C++ network library in a C# project. The solutions are to either create a massive wrapper class in C# to access the required C++ functions, create a C++ wrapper around those functions which can than be used as a COM interop or use Managed C++ (Visual C++/CLI).
I chose the latter which allows me to use C++ to access the RakNet library, but the classes created can be used directly in another .NET project as if. So the main logic has been created in those Managed C++ classes, which also allow me to use the .NET framework and some of its wonderful features. In my C# project I simply need to call the Managed C++ library which provides me with all in all 20 functions I need to perform everything.

Is it possible to use a C++ .lib file from within a C# program?

Is it possible to use a C++ .lib file from within a C# program?
There are plenty of ways. Read about "interop" in MSDN..
One way is to expose the lib as a DLL, and then use pinvoke to call these functions from a C# project. That limits you to a C-style interface, though.
If your interface is more complex (e.g. object oriented) you can create a C++/CLI layer that will expose the lib's class structure to your C# program. This means you'll have to create a managed C++ (or C++/CLI as it's now called) project; then design an interface in managed code that will be implemented by calls to native C++ (i.e. your lib).
Another way of doing this is by wrapping your lib with a COM interface. But COM's a pain, so I wouldn't...
Not directly. You can create a C++/CLI assembly that consumes the lib and then access that from C#, or you can wrap the lib as a DLL.
What you need is a managed wrapper (C++/CLI) around the native C/C++ library that you are working with.
If you are looking for any C++/CLI book I'd recommend Nishant Sivakumar's C++/CLI in Action
Already answered to wrap it but here's an example . Good luck!
I would take a look at swig, we use this to good effect on our project to expose our C++ API to other language platforms.
It's a well maintained project that effectively builds a thin wrapper around your C++ library that can allow languages such as C# to communicate directly with your native code - saving you the trouble of having to implement (and debug) glue code.
No. You can only use a full .dll from a C# program.
That depends, do you have any limitations on this scenario?
If you have a lib file, it should be possible to first compile it into a DLL file, secondly exposing the functions you want to call in the DLL interface, and thirdly, call them using C# native methods (have a look at pinvoke.net on how to do this bit).
you can't use a lib, but like the others said, you can use it if you wrap it into a dll.
swig can take the headers of your .lib, and if they are not too complex it can generate the dll for you which you would then call with a pinvoke from c# which would also be generated by swig.
if your library is complex and has reference counted smart pointers everywhere, you should find an alternative.

Categories