I need to add a new component to a C++ Win32 application (no CLR support) and I would like to implement the new component in C# and use WPF. This new component is basically a window with some controls, which I need to launch quickly from an option in the menu of the Win32 application. The new component and the existing application share some int values and both can modify these values and the other should be notified of changes.
What would be the best way to achieve this?
Thanks
If you want to do this without changing your C++ compilation you might look at calling the .NET assembly as via COM. MSDN describes how to expose .NET Framework Components to COM.
The way I've done this is basically:
Make a COM friendly class and interface in C#
Export the TLB from the DLL
GAC the DLL
Register the DLL using regasm.exe
import the TLB into my C++ code
CoCreateInstance using the __uuidof my C# class
However I haven't tried to do this with a UI component. If the WPF form is a modal dialog you should be OK. If not then I don't know if WPF will be happy with your message loop; you may need to give it a seperate thread so it can run its own loop.
Have you seen the MSDN docs on this subject?
A cursory read implies this is not possible without enabling /clr on your C++ code. if you are able to move to this model then the things you want seem do-able.
btw I would not implement update/signalling code on both sides of the managed/unmanaged boundary for your shared data. Decide where the data lives, and have that code provide a) thread-safe accessors and b) 'update event' wiring that are used by whoever needs to write the data and know about updates.
Check out Observer pattern for a description of how to implement notification to multiple consumers. This may be overkill for your case but useful background.
EDIT:
Until you get the two modules coresident, discussion of event notification design seems premature. If you really cannot build your native code with /clr then I don't see how your WPF component can be used without a separate process, and resulting complexity in interaction and performance hit. Can you re-implement this WPF functionality in native code?
On the other hand - if you plan on making more mods to this codebase, perhaps it's worth considering how hard it would be to port the native code to be /clr-ready. Inline assembler does not prevent use of /clr but it does make it harder, as I am sure you have seen here. My guess is that this would be less work than wiring up the WPF code externally.
The path of least resistance at this point may be to replicate your WPF component in native code. Long term taking the pain of converting your app to /clr may provide a better foundation though. Sorry there is no simple answer.
One way to achieve this is compile your C++ application as a C++/CLI application. Once it's a C++/CLI app, you can mix managed and native code easily, and even talk to managed components with ease.
Rather than mess with COM, I'd prefer to use C++/CLI as a glue layer - that does not require recompiling your entire app as C++/CLI.
That means:
Write the C# code you want.
Write a thin C++/CLI wrapper. This can reference (i.e. dynamically link) to the C# app. All it does is expose a native API around the .NET API. It takes some getting used to, but you can do pretty complex stuff here, including fairly fancy automagic interop via marshal_as. You'll compile this into a dll - a mixed mode DLL.
Your main app now links dynamically to the mixed mode DLL and includes the headers for its API. It can call functions as usual.
This is quite a bit nicer that COM, I think: it doesn't require the GAC, it has a lower overhead should performance ever matter, and exchanging complex datastructures including callbacks & deep object graphs is possible (though there is a learning curve here) quite cleanly by adding custom marshal_as templates/overloads.
Related
Is it even possible to create GUI layer in C# and rest of application in C++? If I am not wrong one of antyvirus software had GUI made in Delphi. How it could be done ?
You have several options for doing it, including:
Use P/Invoke to call into the C++ DLL from C#.
Expose a COM interface from the native code, and call it from C# using COM interop.
Write a native Windows service and call into it from managed code.
Use C++/CLI to write a managed library in C++, which you can easily link to from C#.
If you're starting from scratch, option 4 is probably your best option. (Aside from just writing the whole thing in C#, that is.) The first three options all involve some additional wrangling and overhead, and probably aren't worth the hassle if you don't have a compelling reason such as needing to interact with an existing native library or having some need for a service-oriented architecture.
If you write your business logic in C++/CLI, and your UI in C#, it shouldn't be a problem. If you want to write in pure ANSI C++, you might have to write C++/CLI wrappers around the objects you want to expose to C#.
write the app logic in c++ dll, then use pinvoke from c# to talk to the dll.
See this answer. It seems to answer your problem
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.
I need to port a C/C++ unmanaged project (VS 2008) to C# (preferably .net 3.5).
Are there any conversion-helping
tools; let's say something
translating the code syntax and
asking you verifications/modifications for each
problematic point (I guess I'm dreaming...)
Where can I find some useful howtos or articles about this translation.
They would be very useful if they contained specific hints like:
extern variables should be set in public static classes
(I don't know, I'm guessing...)
Please no suggestion like "You can call your c++ dll from .net", because I know it's possible, but just I can't.
Note:
The C/C++ project uses only STL and
other basic functions, no 3rd Party
libraries etc.
I can't use it directly or wrapped
from C# because our company needs to
mantain/modify the code and we're extremely
more skilled in C# than in C++.
It will cost you far more to convert it than to wrap it and pay a freelancer (like me) to help you out by changing the C++ code for you every few months (or every few years) when you need to make a change. There are some mechanical approaches but the bigger issue is that you can never really be sure that the new C# code does exactly what the old C++ code did. I have clients who have tried this and most gave up and threw the work away. The ones who succeeded did it very slowly, like this:
First, you wrap the old library and get your UI or whatever the new code is (web service, whatever) successfully calling the old library. This gets everyone some "bang for the buck" and buys you time to solve the "we can't maintain our old code" problem. You also develop a comprehensive test suite that proves what the old library does for various edge cases and strange things that only happen in the wild every few years. Over time, you move functionality from the old library into a new C# one and change the calling code to use the new library for that functionality. You move the most volatile parts, the things you change most often, out first. At every stage you run the test cases again to make sure your translation from C++ to C# didn't mess up the results it calculates. Maybe some of it you never move out, maybe in the end it is all moved. You stop when you feel the risk of being unable to maintain your own library and needing to pay someone to do it for you has dropped below the cost of continuing to translate it.
I recommend you have access to someone with good C++ skills when you start. You will probably run into things that don't make much sense to you. But you can get the value from the library pretty quickly, and still solve your underlying problem in the long term.
Depends on what you mean by port.
You can rewrite some of the stuff in C#. Not everything. Some HW or legacy libraries would have to be handled with C/C++ even if you port your own code. I don't know of any reliable automatic converter for C++->C#, and I doubt one can exist.
A better idea may be to wrap your existing code in new C# code. You could create an interop layer in C++/CLI, for example. Or you can communicate with your native code with something like Google Protocol Buffers, if you don't want to mix native/managed code in the same process.
I doubt code conversion tools would help. If you need to make some C++ work in some fashion with .NET, the easiest way is to write a managed C++ layer that wraps it and provides an interface for .NET apps to work with. But it depends on the code.
What is the purpose of rewriting and what does your code do? Does it interface with other components? Does it have a GUI? Is it a standalone executable or a library? Is it a COM / ActiveX server or does it use COM components? Does it link to other DLLs or use 3rd party libraries?
All these affect how you're going to port / rewrite from scratch your app. For example, if your code is an MFC app you may as well forget trying to salvage much code. If your app does http / high level networking stuff you may as well write from scratch. If your code low level you might have to refactor with some C# and some C++ accessible through a managed C++ layer.
Lots of choices and it really depends what your app is doing, how it was written etc.
We have a moderate size (40-odd function) C API that needs to be called from a C# project. The functions logically break up to form a few classes that will comprise the API presented to the rest of the project.
Are there any objective reasons to prefer P/Invoke or C++/CLI for the interoperability underneath that API, in terms of robustness, maintainability, deployment, ...?
The issues I could think of that might be, but aren't problematic are:
C++/CLI will require a separate assembly; the P/Invoke classes can be in the main assembly. (We've already got multiple assemblies, and there'll be the C DLLs anyway, so not a major issue.)
Performance doesn't seem to differ noticeably between the two methods.
Issues that I'm not sure about are:
My feeling is C++/CLI will be easier to debug if there's an interop problem; is this true?
Language familiarity - enough people know C# and C++, but knowledge of details of C++/CLI are rarer here.
Anything else?
In the case where I am working with an existing C library, I prefer PInvoke. PInvoke, while a bit tedious and troublesome at times, is a fairly well understood technology that has an ever growing set of tools and internet documentation available. Generally speaking, whatever problem you run into, there is already a sample available on the web, or a quick check on stack overflow will provide a solution.
C++/CLI is a great technology, but IMHO its documentation is limited as compared to PInvoke for interop specific scenarios. It also doesn't have the tooling infrastructure for interop solutions that PInvoke has. Adding a C++/CLI assembly for a scenario that can be solved with PInvoke just seems too costly to me.
On the other hand, if I'm working with a large C++ library, I consider C++/CLI a bit more. PInvoke does not work with C++, and I must end up adding some kind of intermediate layer. Either a small C layer to wrap all of the C++ function calls or a C++/CLI library to bridge the gap. C++/CLI feels a bit more natural to me in this case.
It depends in large part how memory ownership is handled. P/invoke can marshal pointers only when memory management is one of a couple particular ways, usually caller-allocated buffers. If your API returns pointers (via return value or out parameter, doesn't matter) and expects them to be handed back to a destruction function later... p/invoke will either do the automatic marshaling or give you direct access to the pointer value you need to send back later, never both. So C++/CLI becomes a very desirable approach in that case.
Think of P/Invoke as platform invocation, are you calling into something like the Win32 API which is very P/Invoke friendly or do you need to provide .NET bindings for an unmanaged library?
Since the wrapper typically is very thin a C++/CLI wrapper doesn't necessitate that you know C++/CLI specifically. What you need to know can be found in the language specification, it's an extensive documentation with lots of examples. P/Invoke is more of an nice to have feature for smaller well established existing libraries, but if the interface for calling into that library changes you'll run into a problem. With C++/CLI you can still have a public managed interface in your C++/CLI project that's exposed for managed code and handle changes to the C API more easily that way.
If you wanna get rid of the extra DLL you can always try ILMerge, but I'm not sure if it's capable of handling mixed assemblies, (apparently not), but it looks like it's possible to link both managed and unmanaged *.obj files with the PlatformSDK linker like this:
cl.exe /MD /c /clr Unmanaged.cpp
csc.exe /target:module /addmodule:*.obj Managed.cs
link.exe /DLL /LTCG /NOENTRY /CLRIMAGETYPE:IJW *.obj Managed.netmodule
C++/CLI will be easier to debug if you have personnel who know how to debug C++. If you don't, it could potentially be much harder.
I would suggest that the tradeoff here is between ease of use for the consumers of your interop assembly versus ease of maintainability for the assembly itself. If you have a solid core of senior engineers who are familiar with C++ and who can reliably maintain the assembly, it will be much easier on the rest of your team who are unfamiliar with native code to give them a fully managed interface that takes care of everything for them.
On the other hand, if you're the only person in the shop with C++ experience, I would be very leery of embedding a C++ module into the project, in case someone else has to maintain it later.
For an API of this size (~40 total entry points), I would draw the dividing line between C++/CLI and P/Invoke based on how much "header file gunk" you must duplicate in C#. If it's a small (to modest) amount, P/Invoke is fine. Once you start duplicating a lot of .H files in C#—especially for things that aren't exposed in your .NET API—you might be better off using C++/CLI.
Lots of good answers here - another perspective is the plan for the existing C API.
Arguments for using PInvoke include:
You need to keep a C API around for
compatibility with other C consumers
You need to keep the code in C as
it's large and migration is too
expensive
Arguments for using C++/CLI include:
you want to move as much of the code as possible to the CLR
In this case you can start with C++/CLI and then move more and more over to C#
Basically I have a bunch of unmanaged VC++ static libraries. And the VC++ GUI application which uses those and it is based on MFC.
The goal is to replace the GUI app with the one done in C# instead but using all the same static libraries.
The question is if this even possible, and if yes, then what is the right way to accomplish that?
Suggestions, anybody?
Thanks.
Yes, it is possible using C++/CLI for managed C++ code. You would write a C++/CLI WinForms app and simply link in your static lib as per normal.
However, if there is a lot of tight coupling between the GUI code and the libraries then this can get a bit messy. You will need to worry about converting some data types between the managed and unmanaged world, particularly strings. If you need to pass managed objects/arrays
There is a good introduction on Wikipedia and lots of documentation on MSDN.
Rob is correct - you can do it in C++/CLI entirely, but we found it most useful to wrap some native classes in a managed WinForms User Control class. This managed class contained an instance of the native class, and not only marshalled data like strings in method calls, but also converted native callbacks (implemented with boost::signal) to .NET events. The whole solution for this signal-event translation is spelled out in this question. The .NET WinForms User Control also trapped native exceptions and re-threw them as managed exceptions, and also did some translation of non-.NET interface (methods returning iterators) to a more .NET-styled interface, which you can read about in this question. We were then able to use the .NET class directly in a WPF application. Note that if you wrap it as a .NET class it will have to go in a DLL to be used from C#.