In the process of learning P/Invoke, I asked this previous question:
However, I don't quite understand the implications of using P/Invoke in C# over creating a wrapper in Managed C++. Creating the same DLL using P/Invoke in C# definately resulted in a cleaner interface since I could use DLLImport on an embedded resource, but would a Managed C++ wrapper for a native DLL, where I do the marshaling myself, have better performance?
C++ wrapper should be faster, have a look at this MSDN page:
So basically the main reason is that P/Invoke does pinning, blitting, error checking, while C++ interop just pushes the parameters on the stack and calls the function.
Another point to remember is that C++ can call a several APIs in a single call while P/Invoke EVERY parameter passed by address gets pinned and unpinned on EVERY call, copied and copied back, etc.
Would you get better performance? Depends on what you're doing and how you're doing it. Generally speaking, your performance hit will more likely come from doing managed/unmanaged transitions and the more of those you can cut out the better. Ideally, your interfacing to unmanaged code should be chunky and not chatty.
Let's say that you have a unmanaged code that has a collection of a few thousand objects. You could expose an API like this to managed code:
and that's all well and good, until you start using it in C# like this:
which for total == 1000, will be 4002 managed/unmanaged transitions. If instead you have this:
then you can do the same work with 6 transitions. Which do you think will perform better?
Of course, the next important question to ask is "is this performance gain worthwhile?" so remember to measure first.
One thing you should be aware of as well is that funny things can happen to STL when you're working with managed C++. I have some unmanaged library code which happens to use STL. My experience was that if I ever touched any of the STL types in managed C++, ALL of them became managed implementations. The end result of this was that low level code was doing managed/unmanaged transitions while iterating lists. Yikes. I solved this by never exposing the STL types to managed C++.
In our experience, it is far better (if possible) to go C#->managed C++ wrapper->static library, if you have the ability to do that.