Question

I would like to call my unmanaged C++ libraries from my C# code. What are the potential pitfalls and precautions that need to be taken? Thank you for your time.

Was it helpful?

Solution

This question is too broad. The only reasonable answer is P/Invoke, but that's kind of like saying that if you want to program for Windows you need to know the Win32 API.

Pretty much entire books have been written about P/Invoke (http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X), and of course entire websites have been made: http://www.pinvoke.net/.

OTHER TIPS

There are a couple routes you can go with this - one, you can update your unmanaged C++ libraries to have a managed C++ extensions wrapper around them and have C# utilize those classes directly. This is a bit time-consuming, but it provides a nice bridge to legacy unmanaged code. But be aware that managed C++ extensions are sometimes a bit hard to navigate themselves as the syntax is similar to unmanaged C++, but close enough that a very trained eye will be able to see the differences.

The other route to go is have your umnanaged C++ implement COM classes and have C# utilize it via an autogenerated interop assembly. This way is easier if you know your way around COM well enough.

Hope this helps.

You're describing P/Invoke. That means your C++ library will need to expose itself via a DLL interface, and the interface will need to be simple enough to describe to P/Invoke via the call attributes. When the managed code calls into the unmanaged world, the parameters have to be marshalled, so it seems there could be a slight performance hit, but you'd have to do some testing to see if the marshalling is significant or not.

The easiest way to start is to make sure that all the C++ functionality is exposed as 'C' style functions. Make sure to declare the function as _stdcall.

extern "C" __declspec(dllexport) int _stdcall Foo(int a)

Make sure you get the marshalling right, especially things like pointers & wchar_t *. If you get it wrong, it can be difficult to debug.

Debug it from either side, but not both. When debugging mixed native & managed, the debugger can get very slow. Debugging 1 side at a time saves lots of time.

Getting more specific would require a more specific question.

You can also call into unmanaged code via P/Invoke. This may be easier if your code doesn't currently use COM. I guess you would probably need to write some specific export points in your code using "C" bindings if you went this route.

Probably the biggest thing you have to watch out for in my experience is that the lack of deterministic garbage collection means that your destructors will not run when you might have thought they would previously. You need to keep this in mind and use IDisposable or some other method to make sure your managed code is cleaned up when you want it to be.

Of course there is always PInvoke out there too if you packaged your code as DLLs with external entrypoints. None of the options are pain free. They depend on either a) your skill at writing COM or Managed C wrappers b) chancing your arm at PInvoke.

I would take a look at swig, we use this to good effect on our project to expose our C++ API to other language platforms.

It's a well maintained project that effectively builds a thin wrapper around your C++ library that can allow languages such as C# to communicate directly with your native code - saving you the trouble of having to implement (and debug) glue code.

If you want a good PInvoke examples you can look at PInvoke.net. It has examples of how to call most of win api functions.

Also you can use tool from this article Clr Inside Out: PInvoke that will translate your .h file to c# wrappers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top