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

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/

Related

managed c++ vs com

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.

Mixing managed/unmanaged C++?

I have a library written in standard C++. I also have a .Net windows form app written in C# that utilizes the unmanaged library.
I understand I can just use pinvoke, but my C++ is completely OO and I really wouldn't want to mess around with marshaling and such.
Is there a way that I can just create a new managed C++ dll project, copy and paste my header and code files, and compile it and have access to all the classes?
Or would I have to create some ref class in managed c++ and hook it up to my unmanaged class? I just want this to be as simple as possible.
Thanks!
You would still have to write specific .NET wrappers even in C++/CLI, they just look different. So the answer to, can you put it in a C++/CLI project and recompile and use it as is, is no. You still have to either marshal the data over (in which case you may as well use p/Invoke probably) or you can create handles and use pinned memory to make your structures available to managed code.
I've done this both ways: I've written a GPU library in CUDA C and called it from F# using p/Invoke and I've written a video processing library in C++ and written a thin C++/CLI wrapper then used it in a .NET app. I think the CLI wrapper was more painful, but for live video I needed less latency (less copying memory). For the GPU project I was more concerned with throughput.
You are probably going to want to write the wrapper classes in C++/CLI. It's fairly trivial to do, as long as you return handles instead of pointers, enumerators instead of collections, etc.

CLR C++ VS C++ (pstsdk)

Considering Simon Mourier's answer to this question:
Processing Microsoft Office Outlook 2003/2007 email messages…
I plan to use the PST File Format SDK which is written in C++.
I would take this opportunity to learn more about C++ and to renew with it, since it's been quite 15 years since the last time I used it. I have already downloaded and configured Boost 1.45 which is required to work with pstsdk.
Now, I'm currently writing a Windows Forms application using CLR C++ and plan to use the pstsdk to read from PST files.
Does it matter in any way that I'm using both CLR C++ and pure C++ altogether?
Shall I consider using it a different way, or is this okay?
If you want to use a .NET (Windows Forms, or maybe even the newer WPF) user interface, the simplest approach is to build an object model in C++/CLI, implemented in terms of the native code but having a .NET interface.
Then write the UI in C# and call the C++/CLI object model (which differs from using the .NET base class library in only one way -- you have to add a reference to the C++/CLI assembly... but the C++/CLI compiler will create all the metadata that C# uses).
You can mix managed and unmanaged code, but it will be a pain to marshal everything except the built-in types across the boundaries. It's much easier to stay with more powerful unmanaged C++. You could use CodeGear C++ Builder for example (or QT). The problem with CodeGear is compiler isn't that great, so you won't be able to compile everything from Boost, but you might not need that.
C++/CLI is intended to interop with unmanaged C++- that's pretty much it's entire purpose. However, I feel that it's probably easier to write in C# if you need .NET for, say, WPF, which is an excellent technology, and just use C++/CLI for interop.

Is Winforms accessible from unmanaged C++?

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.

What kind of code library should I build for distribution?

I need to build a C++ library to distribute among our customers. The library must be able to be accessed from a wide range of languages including VB6, C++, VB.net and C#.
I've being using ActiveX controls (ocx files) until now. But I wonder if there is a better kind of library (dll, etc.) that I can build. What do you recommend?
I'm limited to C++ as the library language, but you can mention other languages for reference to other developers.
P.S. Sorry if the question was already asked. I had some trouble finding a suitable title. Feel free to correct my English.
Edit: Seems like the best choice is either DLLs or OCX (i.e., COM), but I'm still having some doubts on which one will I choose. Which one is more suitable to modern languages (.NET for instance)? Which one would be easier to use from an end developer perspective?
Almost every language has a way of loading dynamic libraries and accessing exported C functions from them.
There is nothing preventing you from using C++ inside the dll but for maximum portability, export only C functions.
I have some more about this in this post.
If you're looking at supporting both VB6 and .NET, you're pretty much stuck with exposing interfaces via COM, but at least that'll get you out of having to create more than one wrapper based on the language/runtime system you're trying to interact with.
If there is any chance this will need to be ported to non windows platforms then a DLL / Shared library is your best choice as a COM object really isn't at all portable.
In addition you can call a DLL from almost any platform even if it requires you to write a wrapper of some kind. It's pretty easy to wrap a dll in a com object but if you make a native com object it's a lot harder to add a C style DLL API. Plus you might want to call it from java for example and it's much easier to write a JNI wrapper to call your DLL than get it working with COM in any kind of cross platform way.
Really it depends on what platforms you really need to call it from and how certain you can be that you won't get something out of the ordinary in future.
To be callable from all those languages your only real option is going to be COM, without having to write wrappers where required (which would defeat the point)