Basic guide for using C++/CLI for C# programmer

Basic guide for using C++/CLI for C# programmer

The contents involved in this article are as follows:

  • C + + basic syntax
  • Creating C + + projects in VS
  • Introduction to VS C + + project properties
  • Introduction to C++/CLI
  • Creating a C++/CLI project in VS

C + + basic syntax

// cppclass.h
#ifndef _CPP_CLASS_H_
#define _CPP_CLASS_H_ 

#Include < string > / / use include to include header files

namespace MyClassSpace                    // Defining namespaces 
{
    class BaseClass                       // Define a class
    {
    public:                               // Common parts of the statement
        BaseClass();                      // Constructor
        BaseClass(const std::string& name);
        ~BaseClass();                     // Destructor
        void PrintClassName();            // Class member function
        virtual void Execute();           // Class member virtual function
    private:                              // Declare private parts
        std::string m_name;               // Member variable
    };

    class ChildClass : public BaseClass   // Inherit a class
    {
    public:
        ChildClass();
        ChildClass(const std::string& name);
        ~ChildClass();
        virtual void Execute();
    };
}

#endif

// cppclass.cpp

#include "cppclass.h"

#include <iostream>

namespace MyClassSpace
{
    BaseClass::BaseClass()                        // Constructor implementation
    {
        m_name = "base class";
    }

    BaseClass::BaseClass(const std::string& name) // Constructor implementation
    {
        m_name = name;
    }

    BaseClass::~BaseClass()                       // Destructor implementation
    {

    }

    void BaseClass::PrintClassName()
    {
       std::cout << "This class name is " << m_name << std::endl;
    }

    void BaseClass::Execute()
    {
        std::cout << "BaseClass::Execute" << std::endl;
    }

    ChildClass::ChildClass()                      // Constructor, using the construction of the base class
    : 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;           // using namespace std 

int main()                              // Entry of executable program
{
    const int arraySize = 2;            // Constant definition
    BaseClass* classArray[arraySize];   // Array definition of pointer

    for (int i=0; i<arraySize; ++i)     // loop
    {
        if (i == 0)                     // Conditional judgment
        {
            classArray[i] = new BaseClass(); // new an instance
        }
        else
        {
            classArray[i] = new ChildClass(); // new an instance
        }
    }

    // The output results are as follows:
    // 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();
    }

    // Pay attention to the new object and release it
    for (int i=0; i<arraySize; ++i)
    {
        if (classArray[i])
        {
            delete classArray[i];       // Release new objects
            classArray[i] = nullptr;
        }
    }

    return 0;                           // Function return value
}

Creating C + + projects in VS

  • VS2010, file - > new project, select Empty Project and fill in name, as shown in the following figure:

  • Add the code from the previous section to the project

  • Just compile and run

Introduction to VS C + + common project attributes

General properties

  • Configuration: Active(Debug). It is usually used to set whether the target build is debug or Release. This value can be set in Configuration Manager
  • Platform: Active(Win32). At the same time, set the goal and build it based on 32bit platform or 64bit platform. This value can be set in Configuration Manager
  • General: some general settings, including:
    • Output directory
    • Output directory of intermediate results
    • Target name
    • extend
    • Configuration Type: exe,dll,or lib.
    • Use of MFC: whether to use MFC related libraries, usually not
    • Use of ATL: ATL introduction , usually not
    • Character set: use multi byte character set or use Unicode character set. This refers to the encoding used when compiling source code into binary, which is memory encoding. Unicode: an encoding mode in which all characters are encoded in two bytes; Multi byte: the byte length is not fixed.
    • Common Language Runtime Support: whether to use Common Language Runtime Support is described in the CLI section
    • Whole Program Optimization: global project optimization.

Debugging

At this time, we need to pay attention to three items: Command, Command Arguments and Working Directory.

  • Command refers to the exe program. If the project generates an exe executable file, this item defaults to $(TargetPath). If the project generates a dll program, when debugging is required, this item needs to be set as the executable file loaded into the current dll.
  • Command Arguments: refers to the parameters that need to be passed in the executable file
  • Working Directory: refers to the Working Directory of executable files. If the Working Directory is not set correctly, an error may occur when loading the dependent dll when starting debugging

C/C++ General

  • Additional Include Directories: sets the directory of externally dependent include files
  • Resolve #using Reference: used to specify the directory of #using "some.dll" when compiling with clr
  • Debug Information Format:
    • /Z7: the generated obj file contains all debug information and will not generate pdb files;
    • /Zi: generate pdb files to contain debug information, which can be used together with / Gm Enable minimal rebuild, but / Z7 cannot;
    • /ZI: this option is not normally applicable
  • Common Language Runtime Support: clr related
  • Supply startup banner: displays or does not display version information during compilation

  • Warning Level: usually set to / W4
  • Treat Warnings As Errors: normally set to Yes
  • Multi processor compilation: usually set to Yes
  • Use Unicode For Assembler Listing: it is related to the assembly of output, and its purpose is unclear.

C/C++ Optimization

Generally, the above settings can be kept as default.

C/C++ Preprocessor

  • Preprocessor Definitions: define predefined macros
#ifdef _TEST_
const bool test = true;   // 1
#else
const bool test = false;  // 2
#enif

For the above example code, if you add_ TEST_, Then logic 1 will be executed, otherwise logic 2 will be executed

  • Undefine Preprocessor Definitions: opposite to the above

Other related attributes are generally kept as default

C/C++ Code Generation

  • Enable String Pooling: if this property is enabled, s and t in the following code point to the same memory space.
char *s = "This is a character buffer";
char *t = "This is a character buffer";
  • Enable minimum rebuild: after enabling, when the corresponding header file changes, the cpp source file using the header file will be recompiled
  • Enable C++ Exceptions: the setting for c + + exception throwing
  • Runtime Library: generate dll under release with / MD, dll under debug with / MDD, EXE under release with / mt, and exe under debug with / MTD

C/C++ Advanced

  • Calling Convention: function Calling Convention. If the function calling conventions on both sides are different when using the third-party library, the generated program may report the error of abnormal function stack called by the third-party library when running. See: https://blog.csdn.net/cnhk1225/article/details/53115381
  • Disable Specific Warnings: used to mask specific warnings

Linker General

  • Additional directories: lib additional directories

Linker Input

  • Additional Dependencies: lib file used to set dependencies

Linker Debugging

  • Generate Debug Info: whether to generate debug information. If it is false, debugging cannot be carried out because the corresponding debug related information cannot be found during debugging, such as breakpoint setting.

Linker Advanced

  • Import Library: if a dll is generated and the Lib file corresponding to the dll needs to be output to another folder, this value needs to be set. Such as$ (TargetName).lib

Build Events

If you need to execute some commands before or after the program is built, you can add them in this option. For example, before the program is executed, generate the header file and source file corresponding to proto.

Introduction to C++/CLI

What is C++/CLI

C++/CLI link

The figure above realizes the link between the obj file compiled by CLI and the target file compiled by non cli.

The figure above realizes the link between the obj file compiled by cli and the lib file

The above figure realizes the reference of CLI compiled code to non cli compiled dll

C++/CLI basic syntax

  • Basic type

It can be seen from the above table that in C # different command spaces or the orientation of class members use, The CLI uses::.

  • Managed memory

Managed memory is freed and managed by the garbage collector. The application of managed heap memory uses the keyword gcnew, such as: System::String^ name = gcnew System::String(L'a', 10). It should be noted here that unmanaged types cannot use gcnew to apply for managed memory. In pure c + +, the pointer object is identified with an asterisk *, and the object to which gcnew is connected here is identified with ^. At the same time, the keyword nullptr can also be directly assigned to nameSystem::String^ name=nullptr;.

  • System::String

The operation of System::String is basically consistent with that of c# String.

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

The definition of two-dimensional array is as follows:

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;

// Object array of managed type
// array<System::String> a;  This implementation is illegal and should be
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)
{
    ;
}
  • Custom common type system (CTS) type

// Use ref class instead of class here
ref class ManagedReferenceType
{
    int aPrivateField;
public:
    void APublicFunction();
};

// Define a 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

This keyword has the same meaning as c# readonly in.

ref class MathConstants
{
public:
    static initonly double Pi = 3.1415926; // Direct initialization
}

Creating a C++/CLI project in VS

  • New project

  • Common project properties settings
    • Configuration Platform: select a platform, win32 or x64
    • General - custom output directory
    • C/C++ General: set additional header file directory
    • Linker General: set additional lib library directories
    • Linker Input: set the dependent lib library

Other Resource

  • <<Expert C++/CLI: .NET for Visual C++ Programmers>>

Posted by steve@MRS on Mon, 16 May 2022 06:00:10 +0300