VisaulStudio C#通过C++/CLI托管与原生C++交互

源代码下载地址: https://download.csdn.net/download/sunarmy/87698338

依次创建三个工程:1. C++ DLL动态链接库工程、2. CLR 托管链接库工程 和 3. C# 应用工程

一、创建具有"导出项"的C++"原生"动态链接库

有两种创建方法:

方法1. "具有导出项的(DLL)动态链接库"  或者 "动态链接库(DLL)",适合于新手。

方法2. c++ "动态链接库(DLL)" ,适合于老手。本文使用的是方法2。

1.1 选择新项目类型

 

1.2 设置新项目名称、根文件夹位置

1.3 添加c++文件

添加c++头文件:NativeClass.h 

//NativeClass.h
#pragma once
// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLL_API_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// EXPORTDLL_API  函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef DLL_API_EXPORTS
#define EXPORT_DLL_API  __declspec(dllexport)
#else
#define EXPORT_DLL_API  __declspec(dllimport)
#endif
#ifndef DLL_CLASS_EXPORTS
#define EXPORT_DLL_CLASS __declspec(dllexport)
#else
#define EXPORT_DLL_CLASS __declspec(dllimport)
#endif

class EXPORT_DLL_CLASS NativeClass
{
private:
    int nCount;

public:
    NativeClass(void);
    ~NativeClass(void);
    int GetCount(void);
    void Increase(void);
    void Clear(void);
};

 

添加c++源文件:NativeClass.cpp

//NativeClass.cpp
#include <iostream>
//#include "stdafx.h"
#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;
}

 

 

1.4 确认项目类型为“动态库(.dll)”

1.5 C++生成"原生动态库(.dll)"

 

二、创建 "托管"C++动态链接库 

有两种创建方法:

方法1. " CLR类库(.NET)" ;  适合于新手;

方法2. c++ "CLR空项目(.NET)" 适合于老手。本文使用的是方法2。

2.1 选择新项目类型:CLR空项目(.NET)

 

 

2.2 添加托管C++文件



添加托管C++头文件:WrapperClass.h 

#pragma once
#include "NativeClass.h"
using namespace System;
namespace WrapperClassLib {
    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++源文件:WrapperClass.cpp

#include "WrapperClass.h"
#include "NativeClass.h"

int WrapperClassLib::NativeClassEx::GetCount(void)
{
    return this->m_pnClass->GetCount();
}
void WrapperClassLib::NativeClassEx::Increase(void)
{
    this->m_pnClass->Increase();
}
void WrapperClassLib::NativeClassEx::Clear(void)
{
    this->m_pnClass->Clear();
}

 

2.3 选择C++原生动态库·头文件,所在路径

 

2.4 选择C++原生动态库·库文件,所在路径

  

2.5 配置C++原生动态库·库文件,

2.6  托管C++ 生成 "CLR动态库(.dll)"

三、创建C#工程

3.1 选择新项目类型: C# 应用

本例使用,"控制台应用(.NET Framework)" 。

 

 

3.2 引用管理器添加, 托管C++ 生成 "CLR动态库(.dll)"

 

3.3 添加应用代码C#文件

C#代码中,引用 CLR库命名空间: using WrapperClassLib;

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

using WrapperClassLib;
namespace CsAPP
{
     class Program
    {
        static void Main(string[] args)
        {
            WrapperDllTest.Test();
        }
    }
    class WrapperDllTest
    {
        public static void Test()
        {
            NativeClassEx testCalss = new NativeClassEx();
            System.Diagnostics.Debug.WriteLine("GetCount : " + testCalss.GetCount().ToString());
            testCalss.Increase();
            testCalss.Increase();
            testCalss.Increase();
            System.Diagnostics.Debug.WriteLine("GetCount : " + testCalss.GetCount().ToString());
            testCalss.Clear();
            System.Diagnostics.Debug.WriteLine("GetCount : " + testCalss.GetCount().ToString());
        }
    }
}

 

3.4 生成并运行

通过如下方式,将exe可执行程序 、"原生dll"、"CLR dll", 三者生成在一个目录,直接运行。

生成文件如下:

四、托管与非托管,常见问题:

4.1  fatal error C1189: #error: <condition_variable> is not supported when compiling with /clr or /clr:pure

Ref: c++ - C1189 #error: <mutex> is not supported when compiling with /clr or /clr:pure - Stack Overflow

// nornal.cpp 
#include <cstdlib> #include <atomic> #include <condition_variable> #include <iostream> #include <mutex> #include <shared_mutex> #include <thread> using namespace std;

CLR项目,使用公共语言运行时支持(/clr), 编译normal.cpp 文件出现如下问题:

2>------ 已启动全部重新生成: 项目: WrapperClassLib, 配置: Debug Win32 ------
2>normal.cpp
2>D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include\condition_variable(27,1): fatal error C1189: #error:  <condition_variable> is not supported when compiling with /clr or /clr:pure.
2>.NETFramework,Version=v4.0.AssemblyAttributes.cpp

解决办法:右键点击nornal.cpp 文件, 弹出normal.cpp属性页,把单个文件设置成 "无公共语言运行时支持"

 

posted @ 2023-04-15 16:10  suntroop  阅读(272)  评论(0)    收藏  举报