37

Has anyone worked on calling a C# module from C module. I tried searching on internet but didn't find good examples. Though lot of sites say something like using COM interop but couldn't find a proper example or article explaining it though.

If someone can help me on this, it would be great

Thanks, Sveerap

sveerap
  • 841
  • 1
  • 9
  • 20

4 Answers4

29

There is more than just COM interop if you want to call into managed code from C or C++. The are also the following lesser known methods (taken from MSDN FAQ):

How do I call a .NET assembly from native Visual C++?

There are basically four methods to call .NET assembly from native VC++ code:

  1. CLR Hosting API: Native VC++ module calls CLR Hosting APIs to host CLR, load and call the .NET assembly (sample code: CppHostCLR).

  2. COM Interop: If the .NET assembly can be exposed as a COM component, native VC++ module can call into the .NET assembly through .NET – COM interop (sample code: CppCOMClient).

  3. Reverse PInvoke: The managed code calls native code passing a delegate that the native code can call back (sample code: CSPInvokeDll).

  4. C++/CLI: If the module containing native VC++ code is allowed to enable CLR, the native VC++ code can call .NET assembly directly (sample code: Consuming C# Library in native C or C++ using C++/CLI)

Community
  • 1
  • 1
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
20

Here is a solution. The solution allows calling a C# function from C by decorating your function with [DllExport] attribute (opposite of P/Invoke DllImport).

https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports

C# code

class Test
{
     [DllExport("add", CallingConvention = CallingConvention.StdCall)]
     public static int Add(int left, int right)
     {
         return left + right;
     } 
}

C code

 int main()
 {
      int z = add(5,10);
      printf("The solution is found!!! Z is %i",z);
      return 0;
 }

As @iceflow19 commented below:

The author of the link provides a CLR IL preprocessor as an added step during compilation. Since assemblies use the same binary container format (DLL) on windows, if you manually add the .Net functions offsets in IL to the vtable (the dll's list of exports), Windows is smart enough to invoke the CLR to run that code when called from C. However there is overhead. It's an unadvertised feature. This is how mixed managed libraries in C++/CLI work. To use it just add it through Nuget. The extra target added in your MSBuild project file will provide for the IL preprocessing step

user1741137
  • 4,949
  • 2
  • 19
  • 28
MajesticRa
  • 13,770
  • 12
  • 63
  • 77
  • 7
    I read that link, but he didn't really have an example of using it. What do you need to do in the c project to load the c# (dll?) code? Do you need to `LoadLibrary` `FreeLibrary` etc. – weston Sep 12 '12 at 13:26
  • What would be helpful is a sample .csproj file plus MSBUILD instructions which would allow the student to build the sample application. – V. V. Kozlov Jan 30 '19 at 12:31
  • I don't think this works with latest .NET because it still references 3.5, or at least I couldn't make it work =(. A workaround I think in win10 is downloading the 3.5 framework. I'll try that now – Gaspa79 Jul 25 '19 at 19:49
  • I didn't realize at first that this is is using the `UnmanagedExports` library rather than core library code. – Lyndon Gingerich Feb 24 '23 at 15:05
8

You could expose your C# module as COM:

http://www.codeproject.com/KB/cs/ManagedCOM.aspx

Best method of calling managed code(c#) from unmanaged C++

http://www.codeproject.com/KB/COM/cominterop.aspx

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Madhur Ahuja
  • 22,211
  • 14
  • 71
  • 124
1

There is also the option of building native libraries from C# code using CoreRT and call them from C. Here is an example.

Edit: CoreRT has moved to runtimelab feature NativeAOT. Updated link.

Fabian
  • 1,100
  • 11
  • 14