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.