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

4 Answers 4

30

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)

3
  • Thanks for the help, I will look into them in detail and post my response
    – sveerap
    Dec 13, 2010 at 11:48
  • 1
    Thanks, I tried the COM interop and could do a hello world sort of application.
    – sveerap
    Dec 15, 2010 at 7:09
  • The links for One Code and CLR Hosting APIs are broken. Can you provide an update (I wasn't able to find the correct links)
    – Robot Mess
    Nov 5, 2015 at 13:09
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

4
  • 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, 2012 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. Jan 30, 2019 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, 2019 at 19:49
  • I didn't realize at first that this is is using the UnmanagedExports library rather than core library code. Feb 24, 2023 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

1
  • Thanks, I tried the COM interop and could do a hello world sort of application.
    – sveerap
    Dec 15, 2010 at 7:08
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.

1
  • I have used your link and managed to perform some tests. It works. Thank you
    – Roberto
    Aug 14, 2022 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.