Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a C++ library from C# and .NET?

Tags:

c++

c#

.net

dll

My question is closely related to how a DLL exports C++ classes and generic methods (wrt C++ language features without a C# parallel).

I believe you can call functions inside an extern "C" block from C# by just referencing the DLL and using DLLImport. But can you instantiate a templated C++ type? What if the C++ type does somethin' crazy that's not supported in C#? Is there an RFC or relevant part of the C# specification?

Thanks...

EDIT: I now stumbled across P/Invoke which should be valuable, but I'm still looking for a specification or standard regarding this.

like image 464
Robert Karl Avatar asked Aug 26 '10 20:08

Robert Karl


People also ask

How do I find my C library?

In the gcc manual it is given that "The C standard library itself is stored in '/usr/lib/libc.

Is the C standard library written in C?

In a typical case, the C standard library is written primarily in C, and the C++ standard library primarily in C++. To give some concrete numbers, Microsoft's standard library has ~1050 C and C++ files, and 37 assembly language files.

What is the use of the library in C programming?

Library functions in C language are inbuilt functions which are grouped together and placed in a common place called library. Each library function in C performs specific operation. We can make use of these library functions to get the pre-defined output instead of writing our own code to get those outputs.


3 Answers

The sane way to do it is to use managed c++ to access unmanaged c++ and compile into an assembly.

like image 90
patrick Avatar answered Oct 14 '22 06:10

patrick


I believe you can call functions inside an extern "C" block from C# by just referencing the DLL.

Wrong, you have to use DllImport or so-called PInvoke (Platform Invoke) to call a native C function from managed code. Referencing works only for .NET assemblies or COM with an automatically generated interop dll.

Using C++ from C# becomes a real nightmare because of name mangling among other things.

If you can you could compile a managed C++ Dll as a wrapper to make both worlds meet. This has also the advantage that you can mark your assembly as ComVisible, thus making it available to plenty of tools capable of handling COM.

An alternative is to write a C wrapper around the C++ API, what can be tedious and ugly.

EDIT:

Help to decide which approach to use:

  • 1) You have a native C dll
    • WARNING: if you use a .lib from Managed C++, then the dll is not truely dynamically linked and cannot be replaced with a simple drop in of a newer compatible version.
    • PREFERRED: Use P/Invoke from any .NET language (drop-in replacement possible)

  • 2) You have a native C++ dll
    • DO NOT use P/Invoke, this is a real nightmare (because of name mangling among other things)
    • PREFERRED: Build a wrapper .NET dll with managed C++, works only if you have a compiler compatible with the one that was used to compile the native dll.
    • If the native DLL was build with an incompatible compiler (Compiler A) of the one you can use for managed C++ (Compiler C), then I advise to build (With the same compiler A) a C wrapper around the native C++ dll. Then use the P/Invoke method to use this wrapper C dll like described in 1)
like image 25
jdehaan Avatar answered Oct 14 '22 06:10

jdehaan


What the DLL does internally is irrelevant, as far as C# is concerned. Keep in mind that C++ templates do not generate any code until the template is instantiated. If the template is simply defined somewhere in the DLL header files, then there won't be any generated code for that template in the DLL. On the other hand, if the DLL explicitly instantiates and exports some templated types, then you could theoretically call them from C#.

There are two issues you'd have to overcome. The first is that C++ compilers mangle their method names, so you'd have to figure out exactly what the proper name to PInvoke is. The second problem is that there's no way to create CRT objects in C# directly. You'd have to define some factory methods and export those as well.

Frankly, I think this is all way more trouble than its worth. You'd be better off creating a C-style API for the DLL and calling those functions from C#. Internally, the functions could create and manipulate the relevant C++ objects.

like image 23
Peter Ruderman Avatar answered Oct 14 '22 06:10

Peter Ruderman