受欢迎的博客标签

How to call Unmanaged c++ dll or class within Managed c# project

Published

Some things to consider.

1) The C++ DLL cannot expose C++ things to your C# code. All functionality exposed by the C++ DLL has to be as "C" style functions. You cannot directly create C++ objects or call methods on C++ objects from outside C++. If you need this functionality then create a wrapper project for it. C++/CLI can be used for that.

2) The C++ DLL needs to be built for the same bitness (x86 or x64) as your C# project. If the C++ DLL is x86 then you need to change your C# app to run as x86 as well. If your DLL is x64 then do the equivalent. Any CPU will not work here as the C++ DLL can only support 1 bitness. Note that the default for console apps is Any CPU but prefer 32-bit.

3) Calling native DLLs requires an understanding of marshalling and the rules vary dramatically by what the native function looks like. There is an entire section in MSDN on this complex topic with examples. If there is a specific case you cannot figure out then please post the relevant native function with all inputs and outputs.

c++ dll

To use a DLL function, the name must be exported. It seems that you do not have a .DEF file, but you can add these declarations to your source file:

 

 c# project

The following are the 5 steps required:

declare the function pointer
Load the library
Get the procedure address
assign it to function pointer
call the function using function pointer

 

Here, you will learn the steps for using a simple C++ DLL in C# in .NET Core.

step 1:Create the DLL project.

 

 
 
The solution will look like the following.

 
step2:Add New Item MathLibrary.h in the Source folder.

 
 
step 3:choose Add > New Item. Create a new .cpp file called MathLibrary.cpp
 
 
Write down the following simple code in this .h file. 
#pragma once
 
#ifndef _CREATDEMO_H
#define _CREATDEMO_H
 
 
extern "C" _declspec(dllexport) int add(int a, int b);
 
#endif
 
Write down the following simple code in this .cpp file. 
#include < stdio.h >  
  
  extern "C" {  
    __declspec(dllexport) int add(int a, int b) {  
      return a + b;  
    }  
    __declspec(dllexport) int subtract(int a, int b) {  
      return a - b;  
    }  
  }  

 

 
 
 

 
 
After compiling, you will see the Debug folder as below:
The output will be like this.
 
1>------ Build started: Project: MathLibrary, Configuration: Debug Win32 ------
1>pch.cpp
1>dllmain.cpp
1>MathLibrary.cpp
1>Generating Code...
1>   Creating library C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.lib and object C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.exp
1>MathLibrary.vcxproj -> C:\Users\username\Source\Repos\MathLibrary\Debug\MathLibrary.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Now, our Unmanaged DLL is ready. Let us build a Managed C# App.
The design is like this.
 
The code is as follows. 
 
The output will be like this.
 
using System;

namespace ConsoleAppTestDllImport
{
    using System.Runtime.InteropServices;

    class Program
    {
        [DllImport("MathLibrary.dll", EntryPoint = "sum", CallingConvention = CallingConvention.Cdecl)]
        public static extern int Sum(int a, int b);

        static void Main(string[] args)
        {

            Console.WriteLine(Sum(2,3));
            Console.ReadKey();
        }
}
 
In case of the previous version of .NET , the code will be like below. 

 

 
  1. [DllImport("OurDll.dll")]  
  2. publicstaticexternint subtract(int a, int b);  
  3.   
  4. privatevoid button2_Click(object sender, EventArgs e) {  
  5.   int x = Convert.ToInt32(textBox1.Text);  
  6.   int y = Convert.ToInt32(textBox2.Text);  
  7.   int z = subtract(x, y);  
  8.   MessageBox.Show("Required Answer is " + Convert.ToString(z), "Answer", MessageBoxButtons.OK, MessageBoxIcon.Information);  

The output will be the same for both.


Explanation

extern "C" helps to show all code within brackets from outside.

__declspec(dllexport) int add(int a,int b) is a prefix which makes DLL functions available from your external application.

In .NET Framework 3.5 or the previous version, the code is like -

 
  1. [DllImport("OurDll.dll")]  
  2. publicstaticexternint add(int a, int b);  
For ..NET 4 and above, the code will be liek this.
 
  1. [DllImport("OurDll.dll", CallingConvention = CallingConvention.Cdecl)]  
  2. publicstaticexternint add(int a,int b);  
If you only write framework 3.5 [DllImport("OurDll.dll")], you get an exception -

"… the managed PInvoke signature does not match the unmanaged signature …"


Now, you can call a C++ dll from your C# application (.NET Framework 4)

Thank You!

https://docs.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=vs-2019

 

The following are the 5 steps required:

declare the function pointer
Load the library
Get the procedure address
assign it to function pointer
call the function using function pointer