zoukankan      html  css  js  c++  java
  • C++/CLI for C# programmer使用基本指南

    C++/CLI for C# programmer使用基本指南

    该文涉及的内容如下:

    • C++基本语法
    • VS中创建C++项目
    • VS C++项目属性介绍
    • C++/CLI介绍
    • VS中创建C++/CLI项目

    C++基本语法

    // cppclass.h
    #ifndef _CPP_CLASS_H_
    #define _CPP_CLASS_H_ 
    
    #include <string> // 使用include包含头文件
    
    namespace MyClassSpace                    // 定义命名空间
    {
        class BaseClass                       // 定义一个类
        {
        public:                               // 声明共有部分
            BaseClass();                      // 构造函数
            BaseClass(const std::string& name);
            ~BaseClass();                     // 析构函数
            void PrintClassName();            // 类成员函数
            virtual void Execute();           // 类成员虚函数
        private:                              // 声明私有部分
            std::string m_name;               // 成员变量
        };
    
        class ChildClass : public BaseClass   // 继承一个类
        {
        public:
            ChildClass();
            ChildClass(const std::string& name);
            ~ChildClass();
            virtual void Execute();
        };
    }
    
    #endif
    
    // cppclass.cpp
    
    #include "cppclass.h"
    
    #include <iostream>
    
    namespace MyClassSpace
    {
        BaseClass::BaseClass()                        // 构造函数实现
        {
            m_name = "base class";
        }
    
        BaseClass::BaseClass(const std::string& name) // 构造函数实现
        {
            m_name = name;
        }
    
        BaseClass::~BaseClass()                       // 析构函数实现
        {
    
        }
    
        void BaseClass::PrintClassName()
        {
           std::cout << "This class name is " << m_name << std::endl;
        }
    
        void BaseClass::Execute()
        {
            std::cout << "BaseClass::Execute" << std::endl;
        }
    
        ChildClass::ChildClass()                      // 构造函数,利用了基类的构造
        : BaseClass("child class")
        {
    
        }
    
        ChildClass::ChildClass(const std::string& name)
        : BaseClass(name)
        {
    
        }
    
        ChildClass::~ChildClass()
        {
    
        }
    
        void ChildClass::Execute()
        {
            std::cout << "ChildClass::Execute" << std::endl;
        }
    }
    
    // main.cpp
    #include "cppclass.h"
    
    using namespace MyClassSpace;           // 使用命名空间
    
    int main()                              // 可执行程序的入口
    {
        const int arraySize = 2;            // 常量定义
        BaseClass* classArray[arraySize];   // 指针的数组定义
    
        for (int i=0; i<arraySize; ++i)     // 循环
        {
            if (i == 0)                     // 条件判断
            {
                classArray[i] = new BaseClass(); // new一个实例
            }
            else
            {
                classArray[i] = new ChildClass(); // new一个实例
            }
        }
    
        // 输出的结果如下:
        // This class name is base class
        // BaseClass::Execute
        // This class name is child class
        // ChildClass::Execute
        for (int i=0; i<arraySize; ++i)
        {
            classArray[i]->PrintClassName();
            classArray[i]->Execute();
        }
    
        // 注意new出来的对象注意释放掉
        for (int i=0; i<arraySize; ++i)
        {
            if (classArray[i])
            {
                delete classArray[i];       // 释放new出来的对象
                classArray[i] = nullptr;
            }
        }
    
        return 0;                           // 函数返回值
    }
    

    VS中创建C++项目

    • VS2010,File->New Project,选择Empty Project,填写name,如下图:

    • 将上一节中的代码添加到该工程中

    • 编译运行即可

    VS C++常用项目属性介绍

    通用属性

    • Configuration: Active(Debug). 通常用来设定目标构建出来是Debug的还是Release的。该值可以在Configuration Manager中进行设定
    • Platform: Active(Win32). 同来设定目标构建出来的是基于32bit平台还是64bit平台的。该值可以在Configuration Manager中进行设定
    • General: 一些通用的设置,包括:
      • 输出目录
      • 中间结果的输出目录
      • 目标名字
      • 扩展
      • Configuration Type: exe,dll,or lib。
      • Use of MFC:是否需要使用MFC相关的库,通常不需要
      • Use of ATL: ATL介绍,通常也不需要
      • Character Set: Use Multi-Byte Character Set or Use Unicode Character Set,这个指的是,源代码编译成二进制的时候采用的编码,为内存编码。Unicode:一种所有字符都是用两个字节编码的编码模式;Multi-Byte:字节长度不是固定的。
      • Common Language Runtime Support: 是否使用通用语言运行时支持,在CLI一节中会给出介绍
      • Whole Program Optimization: 全局项目优化。

    Debugging

    此时需要关注的主要是Command,Command Arguments, Working Directory三项。

    • Command指的是exe程序,如果工程生成的就是exe可执行文件,那么该项就默认为$(TargetPath),如果生成的是dll程序,那么需要调试的时候,需要将该项设置成为载入当前dll的可执行文件。
    • Command Arguments:指的是可执行文件需要传入的参数
    • Working Directory:指的是可执行文件的工作目录,工作目录没有设置正确,启动调试的时候加载依赖的dll,可能会出错

    C/C++ General

    • Additional Include Directories: 设置外部依赖的include文件的目录
    • Resolve #using Reference: 当使用clr进行编译的时候,用来指定#using "some.dll"的目录
    • Debug Information Format:
      • /Z7: 生成的obj文件中包含所有的debug information,不会生成pdb文件;
      • /Zi:生成pdb文件来包含debug information,可以和/Gm Enable minimal rebuild一起使用,而/Z7则不能;
      • /ZI:通常情况下不适用该选项
    • Common Language Runtime Support:clr相关
    • Suppress Startup Banner:在编译的时候显示或不显示版本信息

    • Warning Level:通常情况下设置为/W4
    • Treat Warnings As Errors: 通常情况下设置为Yes
    • Multi-processor Compilation: 通常设置为Yes
    • Use Unicode For Assembler Listing: 与输出的汇编相关,不清楚其用途。

    C/C++ Optimization

    一般情况下,上述的设置,保持默认即可。

    C/C++ Preprocessor

    • Preprocessor Definitions: 定义预定义的宏
    #ifdef _TEST_
    const bool test = true;   // 1
    #else
    const bool test = false;  // 2
    #enif
    

    针对于上面的示例代码,如果在该选项中,添加,_TEST_,那么会执行逻辑1,否者执行逻辑2.

    • Undefine Preprocessor Definitions: 与上面正好相反

    其他相关属性一般保持默认

    C/C++ Code Generation

    • Enable String Pooling: 如果启用该属性,那么下面代码中s和t指向的是相同的内存空间。
    char *s = "This is a character buffer";
    char *t = "This is a character buffer";
    
    • Enable Minimal Rebuild: 启用后,当对应的头文件发生变化时,使用该头文件的cpp源文件才会被重新编译
    • Enable C++ Exceptions: 对于c++异常抛出的设定
    • Runtime Library: 生成release下的dll用/MD,debug下的dll用/MDd,relase下的exe用/MT,debug下的exe用/MTD

    C/C++ Advanced

    • Calling Convention: 函数调用约定,如果在使用第三方库的时候,两边的函数调用约定不同,那么生成的程序在运行的时候,可能会报第三方库调用到的函数堆栈异常的错误。具体见: https://blog.csdn.net/cnhk1225/article/details/53115381
    • Disable Specific Warnings: 用来屏蔽特定的警告

    Linker General

    • Additional Library Directories: 额外的lib目录

    Linker Input

    • Additional Dependencies:用来设定依赖的lib文件

    Linker Debugging

    • Generate Debug Info: 是否需要产生debug信息,如果为false,那么在调试的时候由于找不到对应的debug相关的信息,就没法进行调试,如断点设置等。

    Linker Advanced

    • Import Library: 如果生成的是dll,如果需要将dll对应的lib文件输出到另外的文件夹中,那么就需要设定这个值。如..$(TargetName).lib

    Build Events

    如果在程序进行build之前或之后需要执行一些命令,可以在这个选项中进行添加,如,在程序执行之前,生成proto对应的头文件和源文件等。

    C++/CLI介绍

    什么是C++/CLI

    C++/CLI的链接

    上图实现cli编译的obj文件和非cli编译的目标文件之间实现链接。

    上图实现cli编译的obj文件和lib文件之间进行链接

    上图实现cli编译的代码对非cli编译的dll的引用

    C++/CLI基本语法

    • 基本类型

    从上表中可以发现,在C#里面不同命令空间,或类成员的方位使用的是.,在CLI中使用的是::

    • 托管内存

    托管内存受到垃圾收集器进行释放管理。托管堆内存的申请使用关键字gcnew,如:System::String^ name = gcnew System::String(L'a', 10),此处需要注意的是非托管类型不能使用gcnew来申请托管内存。在纯粹的c++中,指针对象是使用星号*标识,此处gcnew的到的对象是用^进行标识的。同时关键字nullptr也能够直接赋值给nameSystem::String^ name=nullptr;

    • System::String

    System::String的操作与c#中String的操作基本保持一致。

    String^ str = string::Empty;
    str1 += "a";
    str1 = str1 + "a";
    str1 = String::Concat(str1, "a");
    String^ str2 = str1->ToUpper();
    
    • Managed Arrays

    二维数组的定义如下:

    array<int,2>^ arr = gcnew array<int,2>(2,2);
    arr[0,0] = 1; arr[0,1] = 2;
    arr[1,0] = 3; arr[1,1] = 4;
    
    // managed type的对象数组
    // array<System::String> a; 这种实现方式是非法的,应该为
    array<System::String^> a;
    
    • Stream-Based IO

    // Read bytes from file
    FileStream^ fs = gcnew FileStream("SampleFile.txt", FileMode::Open);
    int bytesInFile = fs->Length;
    array<Byte>^ bytes = gcnew array<Byte>(bytesInFile);
    fs->Read(bytes, 0, bytesInFile);
    String^ textInFile = Encoding::ASCII->GetString(bytes);
    
    • Managed Exception Handling

    StreamReader^ sr = gcnew StreamReader(arg);
    try
    {
        TextWriter^ tw = Console::Out;
        tw->WriteLine("File {0}", arg);
        DumpTextReader(sr, tw);
    }
    catch (Exception^ exc)
    {
        // Do something
        throw;
    }
    finally
    {
        sr->Close();
    }
    
    • Casting Managed Types
    WebRequest^ req = GetWebRequestFromSomWhere();
    if (dynamic_cast<FtpWebRequest^>(req) != nullptr)
    {
        ;
    }
    
    • 自定义common type system(CTS)类型

    // 此处使用ref class替代class
    ref class ManagedReferenceType
    {
        int aPrivateField;
    public:
        void APublicFunction();
    };
    
    // 定义一个value type
    public value class Point
    {
        int x;
        int y;
    public:
        Point(int x, int y);
    };
    
    gcnew array<V>(100); // V: value type
    gcnew array<R^>(100); // R: ref type
    
    • initonly

    这个关键字和c#中的readonly的含义是相同的。

    ref class MathConstants
    {
    public:
        static initonly double Pi = 3.1415926; // 直接初始化
    }
    

    VS中创建C++/CLI项目

    • 新建项目

    • 常见项目属性设置
      • Configuration Platform:选择平台,win32或者是x64
      • General - 自定义输出目录
      • C/C++ General: 设定额外的头文件目录
      • Linker General:设定额外的lib库目录
      • Linker Input:设置依赖的lib库

    Other Resource

    • <<Expert C++/CLI: .NET for Visual C++ Programmers>>
  • 相关阅读:
    向强大的SVG迈进
    手把手教你写个小程序定时器管理库
    蒲公英 · JELLY技术周刊 Vol.11 Lighthouse 测试报告生成
    ES6语法——let和const
    北京天地益星面经
    JS的数据类型你真的懂了吗
    北京MedPeer凉经
    flex布局语法+实例
    面试官问:你有多少种方式实现三栏布局?
    CSS粘性定位
  • 原文地址:https://www.cnblogs.com/grass-and-moon/p/13687342.html
Copyright © 2011-2022 走看看