How to use C++ code in C#

Why cannot use C++ code in C# directly?

The most remarkable difference between C++ and C# ,i think ,is C++ is unmanaged language rather C# is managed ,which determined you can not write C++ code into the C# code directly,otherwise ,unmanaged code will seems like a runaway train in the managed code

How many ways to use C++ code in C#?

in my opinion ,the ways to use C++ code in C# depends on what you want to call.i just briefly list two type that you want call:

  • C++ function
  • C++ Class
Call C++ function by using Platform Invocation(PInvoke)

PInvoke allows for managed code to call native unmanaged functions implemented as DLLs.this method is ideal for when we have API-like function written in C or C++ that need to be accessed from within a C# program.

NOTE:PInvoke only can be used to Marshall function not to CLass.

The diagram below summarise the PInvake mechanism.

A PInvoke example

Step1 : create Dll project

there is a link aboutcreate DLL project in VS2017

Step2 :Add code for the DLL

  1. Right-click on Project name > Add > Class > Name it something like  Mydll
  2. Add the code that follows
  3. To create the DLL export library: Project > MyDLL properties… > Configuration Properties > C/C++ >Preprocessor > Append, or insert, “DLLDIR_EX” (without the quotation marks) to the Preprocessor Definition text box > OK.
  4. Build > Build Solution
  5. Your DLL should be ready. You should have files MyDLL.dll and MyDLL.lib in directory project-directory\Debug.
Mydll.h

#ifdef DLLDIR_EX
   #define DLLDIR  __declspec(dllexport)   // export DLL information
#else
   #define DLLDIR  __declspec(dllimport)   // import DLL information
#endif 
extern "C" DLLDIR int AddSum(int p1, int p2);
extern "C" DLLDIR void Hello();
Mydll.cpp

//
#include "stdafx.h"
#include "Mydll.h"
#include <iostream>
//using namespace std;
extern "C"{
DLLDIR int AddSum(int p1, int p2)
{
	int sum;
	sum = p1 + p2;
	return sum;
}
}
extern "C"{
DLLDIR void Hello()
{
	std::cout << "hello world" << std::endl;
}
}

NOTE:

.dll is not an app,you cannot run it directly,it is a dynamic libray(dll)that you need to load in host application, in Visual Studio,just “Build”the plugin rather than “Run”it.or you will run into the error follows

.dll is not a valid Win32 application

Step3:Use the Dll in the C# project

add the code below into the c# project


using System;
using System.Runtime.InteropServices;

namespace DllusebyCsharp
{ 
    class Program
    {     
 [DllImport("G:\\oss_sdk_vs_test\\MyDll\\Debug\\MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void Hello();
        [DllImport("G:\\oss_sdk_vs_test\\MyDll\\Debug\\MyDll.dll", CallingConvention = CallingConvention.Cdecl)]

        public static extern int AddSum(int p1,int p2);
        static void Main(string[] args)
        {
            Hello();
            int s = AddSum(3,4);
            Console.WriteLine(s);          
        }
    }
}

other refrence:

Offical Link:Building dll C++ dll in visaul Studio

There is a refrence about: how to creat and use DLL file in c++

There is another refrence about: C+++/C# interoperability

there is an awsome: YouTube tutorial

Call unmanaged C++ Class by using C++ Interop

unmanaged C++ classes can’t be marshaled and that the best approach is to either create bridge/wrapper C-functions for the public methods of the class and marshal the functions, or to create a bridge DLL in managed C++more refrence

there are various ways to call unmanaged C++ class ,it depends on whether The original dll and sources can be accessed or not

  • Solution A: create a function which act as a bridge for each public method within the DLL

build a new myheader.h and mybody.cpp ,and write the code respectively below

header.h

#pragma once
class Myclass {
public: 
	Myclass(int x, int y);
	~Myclass();
	int add();
private:
	int var_x;
	int var_y;
};
mybody.cpp

#pragma once
#include "myheader.h"
Myclass::Myclass(int x, int y) :var_x(x), var_y(y) {}
Myclass::~Myclass() {}

int Myclass::add() {
	int  value;
	value = var_x + var_y;
	return value;
}

what the next is the core file act as bridge between the c++class and C# ,first of all,we creat a new dll project in the VS2017 and add the code named dllclass.cpp below into the project,


#include "stdafx.h"
#include "G:\\oss_sdk_vs_test\\dllPinvok\\dllPinvok\\myheader.h"
#include "G:\\oss_sdk_vs_test\\dllPinvok\\dllPinvok\\mybody.cpp"
extern"C" __declspec(dllexport) int addsum(int a, int b)
{
	Myclass addclass(a, b);
	return addclass.add();
}

ok,lets keep moving on ,call C++ method of class in c#


using System;
using System.Runtime.InteropServices;
namespace dllclasscsharp
{
    class Program
    {
        [DllImport("G:\\oss_sdk_vs_test\\dllclass\\Debug\\dllclass.dll")]
        static public extern int addsum(int a,int b);
        static void Main(string[] args)
        {
            int value;
            value = addsum(23,9);
            Console.WriteLine(value);
        }
    }
}

as you can see,the solution A is not essentially call the class rather than using function directly. you might realize that function above act as bridge to access the original source/Dll,and recompiled DLL,what if the Dll in question is a third party Dll and have you dont have access to the Source so that you can’t recompile the DLL,In this scenario we can use the solution B.

  • solution B: Create a bridge DLL in managed C++

The first thing:

whats the difference between managed c++ and C++?

The second thing:how to use managed C++ or how to wrap the c++ into the manage c++? c++/CLI

during i developed the project ,i found there is no c++/CLI in my vs2017(if you has,you can skip this step),that all come down to you didn’t include the c++/CLI item when you installed the VS .there is a the solution below

launch the VS2017 Installer again->more->modify–>workload–> choose “C++ /CLI Support

okay all set ,lets dig in the code,our code are almost based on this video.and this article there are three parts:

  1. C++ Class(unmanaged c++ which you really want use or the third part source)
  2. C++ wrapper class(CLR,wrap the unmanaged c++ into managed c++ )
  3. C# main controlling engine(use managed c++)

Now ,before we write the code,lets take a look at what we want to do?and what purpose dose each part serve?

obviously,we want to use unmanage C++ in the c#,in other words,we want unmanaged c++ to help C# to deal with something,in this way,we should pass some arguments from the C# to unmanaged c++,but we can not use the unmanaged c++ directly,that is the role the managed c++(C++ wrapper class) play ,it act as a bridge.

the difference between managed c++ and unmanaged c++

so far,we know,we should pass the arguments form c# to mananaged c++ then to the unmanaged c++,that need us to call unmanaged C++ in managed c++(C++ wrapper),but,how to call a member of a class in another class,the solution is let the class(unmanaged class) as the member of another(mnanaged class).