C#调用托管C++库

因为业务需要学习C#调用C++的库

但是C# 是在托管机制的运行

​ C++ 在非托管机制下运行

托管与非托管的区别

指针的运用

托管 是主机自己回收内存,统一释放。
非托管 自己使用内存自己释放。

环境 VS2017
大致实现思路:首先创建C++项目 实现非托管动态库 ,其次在创建C++项目加载非托管运行库,发布成托管运行库,然后C#引用dll库。

具体实现:

创建C#空项目(名称:CsharpDemo)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qt8DoVs0-1648113160602)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\创建C#空项目.png)]

创建C++非托管库(ExportDll)

1.首先在该工程的解决方案上右键->添加->新建项目->Visual C++ -> Windows 通用 -> 空白应用 ,在下面名称地方输入 ExportDll 并选择位置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SLBMeDcZ-1648113160604)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\创建非托管C++空项目.png)]

2.接下来创建类,在ExportDll项目上右键->添加->新建项->c++类 ,输入类名及位置,添加进入下一步,添加类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J5uxOHAD-1648113160605)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\非托管类1.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3NaTmrU5-1648113160605)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\非托管类2.png)]

ExportDllApi.h

//重要代码
#ifdef EXPORTDLL_EXPORTS
#define EXPORTDLL_CLASS __declspec(dllexport)
#else
#define EXPORTDLL_CLASS __declspec(dllimport)
#endif

extern "C" EXPORTDLL_CLASS int Add(int numberA, int numberB);

extern "C" EXPORTDLL_CLASS int Subtract(int numberA, int numberB);

extern "C" EXPORTDLL_CLASS int Multiplication(int numberA, int numberB);

extern "C" EXPORTDLL_CLASS  int Divided(int numberA, int numberB);

ExportDllApi.cpp

#include "ExportDllAPI.h"


EXPORTDLL_CLASS int Add(int numberA, int numberB)
{
	return numberA + numberB;
}

EXPORTDLL_CLASS int Subtract(int numberA, int numberB)
{
	return numberA - numberB;
}

EXPORTDLL_CLASS int Multiplication(int numberA, int numberB)
{
	return numberA * numberB;
}

EXPORTDLL_CLASS int Divided(int numberA, int numberB)
{
	if (numberB == 0) {
		std::cout << "除数不能为空" << std::endl;
	}
	return numberA / numberB;

3.接下来是对该项目的配置, ExportDll项目上右键->属性 进行配置。
在常规属性中配置 输出目录(一般放置在C#项目Debug目录下,后期因为C#程序要加载,尽可能程序库都放置在C#加载的目录下) 和配置类型(配置成动态库)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tN6hKzgz-1648113160606)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\ExportDll属性配置1.png)]
还要配置C/C++中的预处理 加入宏EXPORTDLL_EXPORTS;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LVg4crjJ-1648113160607)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\ExportDll属性配置2.png)]

注意:平台选择Win32

然后在ExportDll项目上右键->生成(或者 重新生成) ,在前面配置的输出目标(C#程序Debug目录下)会生成ExportDll.dll文件。

创建C++托管库(ExportCLI)

1.首先在该工程的解决方案上右键->添加->新建项目->Visual C++ -> Windows 通用 -> 空白应用 ,在下面名称地方输入 ExportCLI 并选择位置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cf7uEX8C-1648113160607)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\创建托管C++空项目.png)]

2.接下来创建类,在ExportCLI项目上右键->添加->新建项->c++类 ,输入类名及位置,添加进入下一步,添加类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDBCFzOF-1648113160608)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\托管1.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ijn35kYD-1648113160608)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\托管2.png)]
ExportCLI.h

#pragma once
#include 
#include "E:\Toshiba\code\TestIPC\CShap\CsharpDemo1\ExportDll\ExportDllAPI.h"

public ref class ExportCLI
{
public:
	ExportCLI();

	int AddCli(int numberA, int numberB);
	int SubtractCli(int numberA, int numberB);
	int MultiplicationCli(int numberA, int numberB);
	int DividedCli(int numberA, int numberB);
};

ExportCLI.cpp

#include "ExportCLI.h"
ExportCLI::ExportCLI()
{
}

int ExportCLI::AddCli(int numberA, int numberB)
{
	return Add(numberA, numberB);
}

int ExportCLI::SubtractCli(int numberA, int numberB)
{
	return Subtract(numberA, numberB);
}

int ExportCLI::MultiplicationCli(int numberA, int numberB)
{
	return Multiplication(numberA, numberB);
}

int ExportCLI::DividedCli(int numberA, int numberB)
{
	return Divided(numberA, numberB);
}

3.接下来是对该项目的配置, ExportCLI项目上右键->属性 进行配置。
在常规属性中配置 配置类型(配置成动态库)和公共语言运行时支持(选择公共语言运行时支持(/cli) )
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pa05EQs8-1648113160609)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\ExportCLI属性配置1.png)]

在 VC++目录 -> 库目录 (一般放置在C#项目Debug目录下,后期因为C#程序要加载,尽可能程序库都放置在C#加载的目录下)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L1Zr7d9s-1648113160610)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\ExportCLI属性配置4.png)]

在C/C++ ->语言 中符合模式选“否”
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dFiZ6w1e-1648113160611)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\ExportCLI属性配置2.png)]

在连接器->输入 附加依赖项加入 ExportDll.lib (上一个C++非托管项目,生成的库问题件)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mk03Li4k-1648113160612)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\ExportCLI属性配置3.png)]

注意:平台选择Win32

然后在ExportCLI项目上右键->生成(或者 重新生成) ,会生成ExportCLI.dll文件。

在之前创建的C#中引用C++库

1.首先进行配置,在项目CsharpDemo项目下面的引用,引用ExportCLI库。
在项目下引用,右键->添加引用->项目 选择ExportCLI
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nSWDaD4H-1648113160612)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\引用添加.png)]
2.在项目CsharpDemo上右键->属性->生成 (平台目标x86)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OKsIN93Y-1648113160613)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\生成平台选择.png)]

3.写入代码
program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CsharpDemo1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("---------c#通过CLI调用C++类方法---------");
                Console.Write("请输入numberA:");
                int numberA = Convert.ToInt32(Console.ReadLine());
                Console.Write("请输入numberB:");
                int numberB = Convert.ToInt32(Console.ReadLine());

                ExportCLI invoke = new ExportCLI();
                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();

        }
    }
}

运行成功!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KfF96qja-1648113160614)(E:\Toshiba\code\TestIPC\csharp-call-cgaga-dll\img\成功.png)]

切记 一定要把CsharpDemo 设置为启动项

源码下载

你可能感兴趣的:(动态调用,c++,c#)