如何用C#用托管和非托管的方法调用C++编写的动态链接库(.dll)?(vs2019)

首先介绍一下什么是托管和非托管

1 托管代码 (managed code)

.NET Framework的核心是其运行库的执行环境,称为公共语言运行库(CLR)或.NET运行库。通常将在CLR的控制下运行的代码称为托管代码(managed code)。

运行库环境(而不是直接由操作系统)执行的代码。托管代码应用程序可以获得公共语言运行库服务,例如自动垃圾回收、运行库类型检查和安全支持等。这些服务帮助提供独立于平台和语言的、统一的托管代码应用程序行为。

托管代码是可以使用20多种支持Microsoft .NET Framework的高级语言编写的代码,它们包括:C#, J#, Microsoft Visual Basic .NET, Microsoft JScript .NET, 以及C++。所有的语言共享统一的类库集合,并能被编码成为中间语言(IL)。运行库编译器(runtime-aware ompiler)在托管执行环境下编译中间语言(IL)使之成为本地可执行的代码,并使用数组边界和索引检查,异常处理,垃圾回收等手段确保类型的安全。

在托管执行环境中使用托管代码及其编译,可以避免许多典型的导致安全黑洞和不稳定程序的编程错误。同样,许多不可靠的设计也自动的被增强了安全性,例如类型安全检查,内存管理和释放无效对象。程序员可以花更多的精力关注程序的应用逻辑设计并可以减少代码的编写量。这就意味着更短的开发时间和更健壮的程序。

简单点说,托管代码是microsoft的中间语言,他主要的作用是在.NET FRAMEWORK的CLR执行代码前去编译源代码,也就是说托管代码充当着翻译的作用,源代码在运行时分为两个阶段:

1.源代码编译为托管代码;(所以源代码可以有很多种,如VB,C#,J#)

2.托管代码编译为microsoft系统的.net平台专用文件(如类库、可执行文件等)。

2 非托管代码 (unmanaged code)

在公共语言运行库环境的外部,由操作系统直接执行的代码。非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务;它与托管代码不同,后者从公共语言运行库中获得这些服务。

在这里我就简单介绍托管的方法了。 编译环境是vs2019。

大家之前可能看的教程大多数都是2010或者17 15 版本的vs,当然这些vs可以直接建立win32项目,
那么2019该如何建立呢?

首先,我们新建项目的时候要这样选择
在这里插入图片描述

在这里插入图片描述
建立好项目之后,就开始编写代码,这里我以一个很简单的代码为例:

首先分别建立h和cpp文件

#include <windows.h>
#include <vcclr.h>
#include <string>
#include <iostream>
using namespace std;

public ref class NativeDog
{
    
    
public:
    void aa();
};
//C++ : nativeDog.cpp
#include "func.h"

void NativeDog::aa() {
    
    
	cout << "11" << endl;
}

当然由于之前我们建立的时候是选择了.dll类型,所以这样是运行不了的,一开始你写public ref class NativeDog的时候会报错,这时候我们需要进行下一步:
在这里插入图片描述
公共语言运行时这一块想必大家懂的都懂,我就不多说了。

继续点击上面的 “生成” 点击生成解决方案, 不报错的话进行下一步。

之后我们需要一个启动项目的程序,这时候就需要用到c#了,在我们cpp的项目在这里插入图片描述
我这里是ddd ,右键 选择 -> 添加 再选择新建项, 然后选择控制台的c#程序。建立完程序之后,我们还需要做重要的工作,一个是找到我们cpp项目文件夹中debug里的ddd.dll文件, 还有一个是需要把这个项目添加到c#项目中,看下图:
在这里插入图片描述
右键 添加引用
在这里插入图片描述

在这里插入图片描述
这两个都需要添加进去,最后c#这样写代码:

// wraptest.cs
using System;
using System.Collections.Generic;
namespace myCsharpTest
{
    
    
    class Programm
    {
    
    
        static void Main(string[] args)
        {
    
    
            NativeDog D = new NativeDog();
            D.aa();
            Console.ReadLine();
        }
    };
}

可以成功运行

当然我举的例子已经是最最最最简单的了,在实际应用中肯定会更加复杂,当用非托管时还会遇到一系列问题,在我其他的文章中也有提到过,比如你还需要用regsvr32注册dll文件什么之类的,所以我觉得还是用托管比较方便吧。

最后再安利一下jetbrains Rider这个 IDEA, jetbrains大法好,rider可以同样可以代替vs完成上面的工作,并且jetbrains系列的界面也很好,rider专门用作c#开发,同时也可以开发unity 近年来还可以使用c++开发虚幻4引擎的项目,游戏开发爱好者的福音!!

猜你喜欢

转载自blog.csdn.net/weixin_45465598/article/details/110008967