第一种方式:C++导出函数, c#dllimport 的方式

在很多地方都看到过,如[dllimport “user32.dll”]这种代码,调用windows API,就是通过这种方式实现。

例子:新建C++项目,创建动态链接库(DLL),然后添加头文件textdll.h

#pragma once
#ifdef A_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
extern "C" DLL_API void MessageBoxShow();   //通过extern “C” 使MessageBoxShow方法为一个导出方法,外部可见 

然后,dllmain.cpp中添加代码:

#include "stdafx.h"
#include "textdll.h"
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
    switch (ul_reason_for_call)
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    return TRUE;
#ifdef _MANAGED
#pragma managed(push, off)
#endif
void MessageBoxShow()
    MessageBox(NULL, TEXT("Hello World"), TEXT("In a DLL"), MB_OK);
#ifdef _MANAGED
#pragma managed(pop)
#endif

编译通过后,找到目录下生成的DLL(TESTDLL.dll),拷贝出来,放到C#的debug目录(程序目录)下, 然后新建C#程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;  //必须要添加该引用
using System.Text;
using System.Threading.Tasks;
namespace dlltest
    class Program
        [DllImport("TESTDLL.dll")]  //最关键的,导入该dll
        public extern static void MessageBoxShow();
        static void Main(string[] args)
            MessageBoxShow();

然后运行可以看到结果:成功的调用了C++DLL中的方法。

第二种方式:

通过C++/CLI作为中间层,因为C++/CLI即可调用.NET的类库,又可调用C++原生库,

所以可以通过C# 调用 C++/CLI 再调用 C++ DLL这样的三层调用方式完成。

1、创建一个c++空项目

  项目创建完成,我们添加一个类,写几个方法,这儿就简单写一个计算器的加减乘除吧!

在CaculateData.h中添加如下代码,定义几个函数声明;

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#ifdef CaculateDLL_EXPORTS
#define Calculate_EXPORTS __declspec(dllexport)
#else
#define Calculate_EXPORTS __declspec(dllimport)
#endif
extern "C" Calculate_EXPORTS int Add(int numberA, int numberB);
extern "C" Calculate_EXPORTS int Subtract(int numberA, int numberB);
extern "C" Calculate_EXPORTS int Multiplication(int numberA, int numberB);
extern "C" Calculate_EXPORTS  int Divided(int numberA, int numberB);
class CaculateData
public:
    CaculateData();
    ~CaculateData();

可以看到,#ifdef的宏没有定义,所以我们需要添加一个宏:

项目右键---属性---配置属性---C/C++---预处理器---预处理器定义,将定义的宏添加进去;

可以看到,定义好了,颜色就变成紫色的,说明已经声明了宏;

在CaculateData.cpp中实现这几个方法;

#include "CaculateData.h"
#include <iostream>
CaculateData::CaculateData()
CaculateData::~CaculateData()
Calculate_EXPORTS int Add(int numberA, int numberB)
    return numberA + numberB;
Calculate_EXPORTS int Subtract(int numberA, int numberB)
    return numberA - numberB;
Calculate_EXPORTS int Multiplication(int numberA, int numberB)
    return numberA * numberB;
Calculate_EXPORTS int Divided(int numberA, int numberB)
    if (numberB == 0) {
        std::cout << "除数不能为空" << std::endl;
    return numberA / numberB;

修改C++工程项目输出目录,这儿主要是便于CLI引用,我们这儿同意定义到Testinvoking项目的输出目录..\bin\Debug\netcoreapp2.2

(修改步骤:项目右键—属性—配置属性—常规—输出目录)

配置类型修改为:动态库.dll (修改步骤:项目右键—属性—配置属性—常规—配置类型)

然后生成;

2、新建一个CLR项目

这个项目就是来实现C#调用C++的

因为需要调用Caculate.dll,所以需要引用它;

配置属性—VC++目录—库目录(把刚刚生成Caculate.dll的路径添加进去)

 同时引用库:

 添加一个类InvokeCon.cpp,用它来调用Caculate.dll中的方法

 InvokeCon.cpp代码如下:

#include "InvokeCon.h"
InvokeCon::InvokeCon()
int InvokeCon::AddCli(int numberA, int numberB)
    return Add(numberA, numberB);
int InvokeCon::SubtractCli(int numberA, int numberB)
    return Subtract(numberA, numberB);
int InvokeCon::MultiplicationCli(int numberA, int numberB)
    return Multiplication(numberA, numberB);
int InvokeCon::DividedCli(int numberA, int numberB)
    return Divided(numberA, numberB);

InvokeCon.h代码:

#pragma once
#include <iostream>
#include "C:\Users\tjy\source\repos\TestInvoking\Caculate\CaculateData.h"//引用库声明对应文件路径
public ref class InvokeCon
public:
    InvokeCon();
    int AddCli(int numberA, int numberB);
    int SubtractCli(int numberA, int numberB);
    int MultiplicationCli(int numberA, int numberB);
    int DividedCli(int numberA, int numberB);

然后编译,修改编译类型为动态库dll

3、c#通过引用CliDll.dll来调用Caculate中的方法

 然后生成:此时就产生了CliDll.dll库

1、添加对Dll的引用;

2、在C#项目中添加测试代码:

可以看到,此时就能够调用多个方法,而且会有方法名提示!

using System;
namespace TestInvoking
    public class Program
        public static void Main(string[] args)
                Console.WriteLine("---------c#通过CLI调用C++类方法---------");
                Console.Write("请输入numberA:");
                int numberA = Convert.ToInt32(Console.ReadLine());
                Console.Write("请输入numberB:");
                int numberB = Convert.ToInt32(Console.ReadLine());
                InvokeCon invoke = new InvokeCon();
                int addResult = invoke.AddCli(numberA, numberB);
                int subResult = invoke.SubtractCli(numberA, numberB);
                int mutilResult = invoke.MultiplicationCli(numberA, numberB);
                int divResult = invoke.DividedCli(numberA, numberB);
                Console.WriteLine($"the {numberA} And {numberB} sum is:{addResult};sub is:{subResult};Mutil is:{mutilResult};div is:{divResult}");
            catch(Exception ex)
                Console.WriteLine($"ex:{ex}");
            Console.WriteLine("执行成功");
            Console.ReadLine();

 OK,完成!

代码已经放到了github,需要的朋友可以去看,就是这篇文章简单的demo:

github地址:https://github.com/tomorrowGooddays/Invoke