We have native Win32 C++ code and a set of C# assemblies which we wish to call from the C++ code. I summaries our optios as:
Use COM. The C# code would need to be decorated with additional attributes (GUID, COMVisible). The C# assemblies would need to be registered regasm and would then be available to the native C++ code via COM.
Use a C++/CLI (formerly managed C++) wrapper class. A C++ class could be added to the native C++ project. That class would be compiled with /clr. The native C++ code would call the C++/CLI class which would then call the .Net code. No COM involved. The CLR is started by magic as required with marshalling handled by the C++/CLI extenstions.
Host an instance of the CLR in the native C++ code.
I'm going to discount option 3 as I don't see the benefits over option 2 other than we lose the need for a wrapper class. So the question is, what are the pros/cons of option 1 versus option 2?
Thanks in advance.
Option 2 will perform the best, and be the most seamless and maintainable, IMO.
There is really no advantage to option 1 that I've found. Using C++/CLI seems to function much better, work faster, and be much simpler in general.
You also can, btw, just use the C# assembly directly without having a wrapper class. This does require compiling any files that want to use it with /CLR, but it works quite well.
For option 1 your main pro would be not having to write a wrapper class which can get hairy depending on your project.
For option 2 you won't have to modify your managed library to facilitate unmanaged use, which is sometimes not an option.
For me it comes down to where you want to make your code changes.
With option 2 you also have a pretty straightforward way of subsequently convert your whole application to C++/CLI to avoid the managed/unmanaged transitions that you will get. The transitions could be an issue depending on how you use your referenced assemblies i.e. getting a performance hit.
So far I have had only positive experiences with C++/CLI and can recommend going that route.
Related
Good day,
I want to take an existing C# project and wrap functions into a C++/CLI DLL. I need to be able to read this DLL from VB 6. I choose this route because I won't have to register a .net DLL in order to use it with VB 6. Frankly I have no experience with this kind of thing so I would greatly appreciate a good example. I know there are plenty of similar questions like this but I haven't been able to find anything simple enough for me to understand.
This is a fairly unwise route to pursue, making C# code [ComVisible] is pretty trivial and Regasm.exe should not scare you. The usual mistake with Regasm is to forget to use its /codebase option on your dev machine.
If you insist on not taking advantage of this then you'll need to find a way to get the CLR loaded yourself so it can execute your C++/CLI and C# code. There are three basic ways to do so. You've written off COM interop and hosting the CLR yourself isn't very practical if the host app is VB6. You however can take advantage of the C++/CLI compiler's ability to generate unmanaged DLL entrypoint stubs that load the CLR for you and switches to managed code execution. Do so by writing a static function that you decorate with __declspec(dllexport). The technique is shown in this answer. Beware that it isn't particularly performant and you'll have to live with the restrictions imposed by the VB6 Declare statement.
Also check this post-processing tool that can inject these stubs directly into a C# assembly. Not sure how reliable it is, I haven't used it myself.
Be a man and make that DLL under a couple of different compilation/linking/function-call-protocol configurations. Then go ahead and try a couple of different referencing configurations in your VB6 project. Post what works. Contribute, go forth!
Take a look at Export Managed Code as Unmanaged
and C# Project Template for Unmanaged Exports
I was wondering if the two following scenarios have the same performance impact on native C++ code (if there is any performance impact at all).
Let's assume I have the function cpp_calc() that is doing some calculation stuff and is written in native C++. Also, there is cs_show_gui_stuff(), which is written in C#.
Now, which of the following scenarios will worsen the native c++ performance (if there is any performance penalty at all)?
Creating a .Net (C#) application that runs cs_show_gui_stuff() and calls cpp_calc() in the native C++ dll using DllImport or turning C++ into a COM DLL.
Creating a C++ application that implements cpp_calc() in C++ and runs cs_show_guid_stuff() by placing the C# code in a .Net COM DLL.
Thanks :-)
It really depends on what the other parts of the system are mainly written in. From a performance-only perspective, one PInvoke (via DllImport attribute) call will probably be faster than one COM call if the method arguments do not need any special marshaling.
A third, and probably the best alternative, is to create a managed C++/CLI library that calls the unmanaged C++ method with nearly no performance impact and add a reference to the C++/CLI library in the C# application. The C# application can then make managed method calls to the C++/CLI application, which in turn can make unmanaged method calls. While this adds one level of indirection, it will provide way better performance than the methods you mentioned.
Either way You are going to bump on Just-In-Time compiler. I guess the penalty is the same on both scenarios. I would personally choose the first one, because .NET libs are more robust on the GUI - WPF, Silverlight, WinForms, WebForms, Razor ... You see what I mean.
I have a native C++ DLL using DirectX, that I want to be able to use through C# to be able to create content creation tools.
Adding COM would require quite an effort it seems.
Can P/Invoke be used to maintain classes using polymorphism, or would it require me to wrap most of the code to facilitate use of P/Invoke?
It there a better solution is available? Or should I even consider writing the tools in C++ using Qt perhaps?
I always feel that C++/CLI is always the best option when doing C# to C++ interop. You can easily create thin wrappers for an unmanaged library that will look exactly like a managed library to your C# code. It also gives you more control over how marshaling and pinning is performed.
There are ways to automatically generate C++/CLI I believe, but I've never used them.
More info on C++/CLI here:
http://msdn.microsoft.com/en-us/magazine/cc163681.aspx
I presume rendering with D3D directly from C# isn't an option? (because that certainly would be easier!)
A long time ago, I used SWIG to automatically maintain C# "bindings" of my C++ rendering DLL code. It uses P/Invoke to expose the C++ objects on the C# side, and you won't have to maintain that code anymore.
You don't need to write wrap on QT.
I advice you to write Observer class both in C# & C++, and hide calls of Native functions to it.
Schema is like this
Your code in C# -> Observer(C#) -> Native call to Observer(C++) -> Calls to your dll.
I have been keeping up with .NET CLR for awhile now, and my language of choice is C#.
Up until recently, I was unaware that C++/CLI could produce "mixed mode" executables capable of running native and managed code.
Now knowing this, another developer friend of mine were discussing this attribute and trying to determine when and how this ability would be useful.
I take it as a given that native code has the capability to be more efficient and powerful than managed code, at the expense of additional development time.
In the past, I resorted to strictly native C++ code libraries and used Interop to make use of the functionality I wrote into the native library.
I can see the benefit of not requiring an additional library, but I'm curious as to what all the pros/cons of using C++/CLI over soley managed executable created in C#, or such an executable using Interop to call a purely native C++ library?
(Sidenote: Are the terms Interop/PInvoke interchangeable, as I d.on't understand the difference between the terms, simply seen them used the same way.)
With C++/CLI you can create, broadly speaking, three types of objects:
Managed types. These will compile down to essentially the same IL as the equivalent C#. There is no performance opportunity here.
Native types. Compiles down to native code as if you'd used straight C++.
Mixed mode types. These compile down to managed code, but allow you to refer to native types too.
You might think of (3) as being like writing C# code with PInvoke code to accessing the native stuff - except all the PInvoke stuff is generated for you.
There's more to it than that, of course, as well as some caveats - but that should give you an idea of how it's useful.
In other words it's really a glue language. While you can write fully fledged apps in C++/CLI it's more normal to keep the managed and native parts separate and use C++/CLI to bridge the two more cleanly than with PInvoke.
Another common use is to extend and existing, native, C++ code base with .Net library calls.
Just be careful that you partition your code well as it can be quite subtle sometimes in compiling your pure C++ code down to IL transparently!
As to your sidenote: PInvoke is a particular type of Interop. Interop comes in other forms too, such as COM Interop. In fact, more accurately, PInvoke is a set of language features that make Interop with native code easier.
I've used Managed C++ (the .NET 1.1 precursor to C++/CLI) effectively in the past. I find it works best when you have a native C or C++ library you wish to use in managed code. You could go the whole Interop/PInvoke route, which makes for some ugly C# code and frequently has marshalling issues, or you could write a managed C++ wrapper, which is where C++/CLI really shines.
Because C++/CLI is managed code, you can call it from C# (or VB.NET if you lean that way) in the normal way, by adding a reference to the .DLL. No marshalling, no dllimport, nothing goofy like that. Just normal project references. Additionally, you get the benefit of static linked libraries if your native library is so designed, which is a Good Thing (tm).
Phil Nash really hit the big things. Here's one more that I've hit more than once and is the primary reason I've used C++/CLI in the past:
Some applications are extended by checked all DLLs in some location for exported functions with a particular name. In C#, there's no way to declare a native C-style export, but you can in C++/CLI. I create a "wrapper" in C++/CLI that exports the method, handles any translation of C structs to managed objects and passes the call on to an assembly written in C#.
There are certain types that are not available to other languages, such as templates,
const and tracking handle of boxed value types.
templates are specialized at compile-time. generics are specialized at runtime. Although CLR should cache generics specialization for future use (so you get the same List each time you use it), there is still a performance hit each time a generics specialization is requested.
i know other languages discard the const attribute, but have compile time checking in your C++ code is better than nothing.
Having a type like int^ allows you to access the memory on the managed heap directory without unnecessary unboxing. This can help performance when passing tracking handles of boxed values to functions that expect a tracking handle, such as Console::WriteLine(Object^). Of course the early boxing initialization can not be avoided. In other languages you can store the reference in an Object variable and pass it around to avoid unboxing, but you lose the compile time type check.
Is there a way to create C# objects and call methods from unmanaged C++, but without using COM Iterop? I am looking for something like JNI (but for .Net), where you can manually create the VM, create objects, etc.
If you are using C++/CLI then you can interact directly with both the managed world and unmanaged code, so interop is trivial.
You can also host the CLR yourself, and whilst the hosting API is COM based, you can then create any managed object. The process isn't a difficult as it sounds as a few API calls encapsulate a lot of functionality. There is a lot of info online, for example the MSDN documentation on "Hosting the Common Language Runtime".
There is a somewhat "undocumented" way of exporting C style API from a .NET class / method.
This ultimately leads to a situation where a .NET dll has exported APIs that can be called from C/C++ or anything that can consume .DLLs for that matter.
If you are into "reading" (beh ;) you can get a book called: Inside Microsoft® .NET IL Assembler where you'll find this technique in chapter 15: "Managed Methods as Unmanaged Exports"
There's also a nice example project on code-project you can use as a starting point for 32-bit environments:
http://www.codeproject.com/KB/dotnet/DllExport.aspx
You can decide file-by-file in your C++ project whether or not to use managed C++. Try changing the settings a file in your project so that it compiles as managed. Put the calls there to your C# object.
There's a cost to crossing the C++/C# border, so you should analyse where to do it. Like, you wouldn't want to do it inside a loop.
I am author of jni4net, open source intraprocess bridge between JVM and CLR. It's build on top of JNI and PInvoke. No C/C++ code needed. I hope it will help you.