15

I have a pretty big system implemented in C++ I need to interact with. The system has a pretty big API, a number of C++ DLLs. These DLLs export C++ classes, as opposed to a nice C style API. and I need to use them from a new C# project.

From what I know .NET has three ways of interacting with native software:

  1. P/Invoke - which works only on C APIs
  2. COM objects
  3. C++/CLI

So the way I understand it, I have three approaches accordingly:

  1. Writing a wrapper in C and calling it with P/Invoke. which seems way too much work.
  2. Writing a wrapper with COM. which I don't know how to do, and unless it's insanely easy i'm reluctant to learn what seems to me - a dying technology .
  3. Writing a wrapper in C++/CLI. which seems the least work, though still a lot.

My question:

  1. First of all I would like to know why doesn't .NET allow me simply to use the C++ classes "as is"? I'm assuming it's a matter of memory management. and if it is I'm more than willing to write finalizers, and implementing IDisposable . From what I know C++ classes are just really fancy structs, and since P/Invoke supports structs, and functions that take structs as the first parameter, why not support classes?

  2. Second, assuming I'm really lazy, and its a lot of boring, tedious, work, What would be the best way to use these DLL's? a possibility to call them directly from C# would be the best. If not then I'd love an automatic tool to produce the wrappers. Also, the DLLs might change, probably, just slightly but still, id rather not be forced to manually re-write wrappers.

For a really good answer, especially on the first part, or a good automatic tool, I'll reward a bounty...

Thank you

AK_
  • 7,981
  • 7
  • 46
  • 78
  • 1. Because different DLL's have different calling conventions. – Robert Harvey Apr 04 '13 at 22:27
  • 2
    http://stackoverflow.com/questions/2120690/tool-for-creating-net-wrappers-for-a-com-dll – Robert Harvey Apr 04 '13 at 22:27
  • I think C++/CLI would be good. I don't exactly have experience doing this with C++ exports, though. – chris Apr 04 '13 at 22:28
  • 2
    [Cxxi](https://github.com/mono/cxxi) sounds like what you want, but I'm not sure how usable it is yet. – Mark H Apr 04 '13 at 22:28
  • @RobertHarvey , Its handled just fine in P/Invoke for C calling conventions, And the C++ system is using VC++ ... – AK_ Apr 04 '13 at 22:34
  • Well, you have to tell it how to interact with the DLL somehow. `extern` declarations seem as good a way to do that as any other. .NET assemblies can be referenced directly because they already contain metadata that describes the entry points. – Robert Harvey Apr 04 '13 at 22:36
  • 3
    I'd imagine the main reason for not supporting C++ classes is because C++ does not have a standardized ABI. And no, C++ classes aren't *just fancy structs*. A given class might be using [virtual] multiple inheritance for example. The behind the scenes implementation of that is completely up to the discretion of the compiler vendor for example. – greatwolf Apr 04 '13 at 22:41
  • @RobertHarvey , I'm willing to tell it whatever it wants to know, I'm even willing to write, myself, a tool that will generate extern declarations. What i'm not willing to do, is writing a lot of wrapper code by hand. and wore **maintaining** it. – AK_ Apr 04 '13 at 22:41
  • 2
    My searches of the Internet's tubes seem to be that it is easiest to write your own managed C++ to act as wrappers for the unmanaged C++. Check out this write up of the P/Invoke versus the bridging managed C++ DLL at: http://www.codeproject.com/Articles/18032/How-to-Marshal-a-C-Class – StarPilot Apr 04 '13 at 22:48
  • StarPilot is correct, using C++/CLI as a "glue" language is the best option when you need to interface between .NET and native C++ code. – Cody Gray - on strike Apr 05 '13 at 05:51
  • I suppose it also depends on the number of C++ classes. Why would you expose 1000 C++ classes to .NET as is? Most of the time, we expose a subset of the C++ classes, a "service-like" facade, and if you look at how Microsoft did it for GDI+ for example, they just exposed some of it using simple DLL Exports and build a new set of .NET style object in C#. I think its good to have a clean contract between the C++/unmanaged world and the .NET/managed world. Keeping a full mix between the two worlds is a burden IMHO. – Simon Mourier Apr 05 '13 at 06:04
  • Every time I work with C++ I get more and more convinced that it sucks. – AK_ Apr 06 '13 at 14:54

2 Answers2

6

If you are willing to go the lazy way I would suggest using a tool to generate C# wrapper for your C++ classes. And of course the tool for generating such a wrapper is SWIG

For more information, see my old answer to similar question

Community
  • 1
  • 1
user544511
  • 759
  • 6
  • 15
  • I'm accepting your answer for the SWIG suggestion. though we ended up using P/Invoke to a C Wrapper. – AK_ Apr 13 '13 at 20:25
0

The way I understand it, in C++ the calling conventions for methods in classes are quite messy. At the level of the .LIB files that are used by the linker, the function names get "decorated" (see e.g. Name mangling). Also, the layout of class variables in memory is presumably different between all the different implementations of C++ compared to C#, which is why Interop Marshaling is such a big topic. So my guess is that Microsoft judged that there are too many low level issues, and hence too hard, to make it worthwile.

I've used both P/Invoke and COM objects to link my C# to C++, but I haven't used C++/CLI. I've been dabbling in COM for years, and it's very much like it's own language. So if you've never done any COM I think you're right that it's not worth learning it at this stage. If a C++/CLI would let you interface to the objects, rather than having to squeeze everything through a C interface, then I think you're right that it'll be the best route.

Stochastically
  • 7,616
  • 5
  • 30
  • 58