Call C# DLL from C++ application
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

The following article shows you how to accomplish what I need to do using Visual Studio 2005:

https://support.microsoft.com/en-gb/help/828736/how-to-call-a-managed-dll-from-native-visual-c-code-in-visual-studio-n

Attempting the same steps in Visual Studio 2017 results in failure. Errors include:

  • object of abstract class type 'ManagedDLL::ICalculator' is not allowed
  • no instance of constructor matches the argument list
  • cannot instantiate abstract class
  • cannot convert argument 1 from 'const _GUID' to 'const ManagedDLL::ICalculator'

This bounty is to provide a Visual Studio 2017 example of the equivalent code that compiles, runs and works. The C# DLL should be written in .NET Framework 4.6.1.

Do you need managed C++ (CLR) or normal C++ for your code? Also, $10 may just be a bit low for the bounty.
thelostt 1 month ago
Normal C++ - thanks!
Chris Wood 1 month ago
Sorry - forgot to comment on the bounty. I based it on the assumption that the link I provided gives most of the code and that the steps would've changed in some minor ways that elude me.
Chris Wood 1 month ago
awarded to thelostt

Crowdsource coding tasks.

1 Solution

Winning solution

Installing UnmanagedExport with NuGet

  1. Create a C# Class Library solution (required before instaling UnmanagedExport). I'm naming it ExportedCodeSolution for the examples.
  2. Go to Tools > NuGet Package Manager > Package Manager Console.
  3. A console will show up at the bottom of VS. Type in this line:

    Install-Package UnmanagedExports -Version 1.2.7

Setting up solution

NuGet will issue that your solution has no platform target. To change that,
go to the dropdown menu box where it says "Any CPU" (it's side by side with
the Debug/Release dropdown menu box). From there, click on Configuration Manager.
On "Active solution platform", select one of x86, ia64 or x64. If you run a 64 bits
system, select x64. Select x86 otherwise. Then close it.

Now import RGiesecke.DllExport in order to use the attribute.

The following is a code example:

// ExportedCodeSolution.Class1
using System;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;

namespace ExportedCodeSolution
{
  public class Class1
  {
    // If you want more examples of this, access:
    // https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports

    // You can also use Cdecl and others instead of StdCall.

    [DllExport(ExportName = "maxElement", CallingConvention = CallingConvention.StdCall)]
    static public int maxElement(int a, int b)
    {
      Console.WriteLine("Wow, numbers are {0} and {1}!", a, b);

      if (a > b)
        return a;
      else
        return b;
    }
  }
}

Create a C++ console application solution. Name it however you want.
Use this code as an example to load the exported function.

#include <cstdio>
#include <Windows.h>

// If you used CallingConvention.Cdecl, change this _stdcall to __cdecl.
using MaxElementFn = int(__stdcall *) (int a, int b);

int main()
{
  HMODULE mod = LoadLibraryA("ExportedCodeSolution.dll");
  MaxElementFn maxElement = reinterpret_cast<MaxElementFn>(GetProcAddress(mod, "maxElement"));
  std::printf("max: %d\n", maxElement(1, 2));
}

Note: change your build to use x64 instead of x86. Copy-paste the DLL from
the ExportedCodeSolution directory
ExportedCodeSolution/ExportedCodeSolution/bin/x64/Release/ExportedCodeSolution.dll
to <your C++ solution>/x64/Release/ExportedCodeSolution.dll.

Build and run the C++ solution in Debug > Start Without Debugging. This should be the output from the console:

Wow, numbers are 1 and 2!
max: 2
Press any key to continue . . .

If you get any issues, let me now!

Brilliant! That worked first time! Thanks!
Chris Wood 1 month ago
Thank you ^^
thelostt 1 month ago