C# 控制台应用程序调用 C++/CLI 动态库(托管方式)

844 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

上次我们尝试了C#调用C++ 的非托管方式,为了实现 C++ 和 C# 的更好的交互,我们这节来探讨一下C# 调用 C++/CLI 的托管方式。在项目开发的过程中,我们知道有些很好用的库仅仅是 C++ 编写的,要想将 C++ 和 C# 项目一起使用,有个好的方法就是:P Invoke。为了使二者更好的交互,可以将现有的 C++ 类库,封装成 C++/CLI(托管C++)。记住我们的目标 C# 调用 C++,那么我们就来一起尝试一下吧~

一、创建 C++ 项目

  • 创建C++空项目

    image.png

    image.png

  • 命名为 ManageLibrary

    image.png

  • 进入属性

    image.png

  • 可以导入提前生成的属性

    截屏2022-11-30 下午11.37.06.png

  • 添加现有属性表

    image.png

    image.png

  • 或者手动配置如下属性

    image.png

    image.png

    image.png

  • 配置输出目录

$(SolutionDir)Build$(Platform)$(Configuration)

  • 创建一个类

    image.png

NativeClass.h

#pragma once 

class NativeClass
{
private:
    int nCount;
public:
    NativeClass(void);
    ~NativeClass(void);
    int GetCount(void);
    void Increase(void);
    void Clear(void);
};

NativeClass.cpp

#include "NativeClass.h"

NativeClass::NativeClass(void)
{
    this->nCount = 0;
}
    NativeClass::~NativeClass(void)
{
}
int NativeClass::GetCount(void)
{
    return this->nCount;
}
void NativeClass::Increase(void)
{
    this->nCount++;
}
void NativeClass::Clear(void)
{
    this->nCount = 0;
}

二、将 C++ 类库封装成 CLI

CLI = Common Language Infrastructure,需要使用 CLI 的时候,我们就必须配置项目属性,设置公共语言运行时支持(/clr)

  • 关键字 ref 加在类之前声明是CLI/CLR 。
  • ^处理对象(Object)操作,代替*指针
  • gcnew代替new去分配内存
#pragma once
#include "NativeClass.h"

namespace ManageLibrary {
	public ref class NativeClassEx
	{
		// TODO: 在此处为此类添加方法。
	private:
		NativeClass* m_pnClass;
	public:

		NativeClassEx(void)
		{
			this->m_pnClass = new NativeClass();
		}
		~NativeClassEx(void)
		{
			delete this->m_pnClass;
		}
		int GetCount(void)
		{
			return this->m_pnClass->GetCount();
		}
		void Increase(void)
		{
			this->m_pnClass->Increase();
		}
		void Clear(void)
		{
			this->m_pnClass->Clear();
		}
	protected:
		!NativeClassEx(void)
		{
			delete this->m_pnClass;
		}
	};
}

三、C# 类库

  • 创建C#项目

    截屏2022-12-01 上午12.36.43.png

    更多细节可以参考之前的文章的第三章,如果你不想当前的C#项目作为类库被调用你也可以创建C#的控制台应用程序。

  • 解决方案右键 创建 C# 控制台应用程序

    image.png

  • 选择 Console App

    image.png

  • 命名为 ConsoleApplication

    image.png

  • 点击创建

    image.png

  • 设置 C# 的 ConsoleApplication 为启动项目

    image.png

  • Build Dependencies:生成依赖项-项目依赖项

    截屏2022-12-01 上午12.36.43.png

    image.png

  • 创建 cs 文件代码,测试 C++ CLI 动态库里的类函数

    using System;
    using ManageLibrary;
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                NativeClassEx testCalss = new NativeClassEx();
                Console.WriteLine("GetCount : " + testCalss.GetCount().ToString());
                testCalss.Increase();
                testCalss.Increase();
                testCalss.Increase();
                Console.WriteLine("GetCount : " + testCalss.GetCount().ToString());
                testCalss.Clear();
                Console.WriteLine("GetCount : " + testCalss.GetCount().ToString());
    
                Console.WriteLine("Hello World!");
            }
        }
    }
    

    对于 C# 控制台应用程序,引用需要的 C++ CLI 动态库,使用 using 语句就可以使用对应的命名空间中的类及里面的函数。

  • 测试结果如下

    image.png