Analysis on Calling C ++ DLL in C # (2) -- generate a hosted dll

Source: Internet
Author: User

Before writing, I would like to briefly introduce the differences between hosting and non-hosting C ++. In fact, I have not thoroughly understood the features of hosting C ++, the biggest feature is that the system can debug and recycle relevant code resources. Like C #, the programming style is similar to C ++. Therefore, this determines that C # can be perfectly integrated with hosted C ++. It should be said that the dll generated by hosting C ++ is no different from the dll generated by C #. The reason for the creation of a host C ++ monster is that Microsoft is strongly advocating C #, interaction between different languages must be considered.


Well, let's take a look at the process. I have a class ClassA written in C ++. I want to call this class under C, however, C # does not have a simple method like dllimport to obtain classes in unmanaged C ++ dll. My solution is to generate a dll hosting C ++, because the hosted code and unmanaged code cannot be mixed in a file, therefore, I have to encapsulate ClassA with the method of hosting C ++, and then generate a dll for C # to call.


I may be very confused here. Please refer to the following tutorial and it will be very clear.


1. Create a CLR Class Library Project


In fact, I 'd like to ignore these steps. I don't want to mention the problems that can be illustrated in a picture. Anyway, to create a CLR class library project, its name is tentatively set to ManageClass. This is the project name, do not confuse. For example, there are no precautions. I complained that BKJIA could not narrow down the image in the editor, which is very troublesome)

650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/2000215137-0.jpg "title =" 1.jpg" alt = "205824549.jpg"/>


2. An example of unmanaged C ++


I have a NativeClass class written in a non-hosted C ++, which itself belongs to another unmanaged C ++ project, now I directly copy this class file to the directory of this project. For the sake of simplicity, I inline this class in a header file. If it is another relatively large class, it is necessary to copy NativeClass. other files # include in h are also copied to the directory of the new project, and then added to resource manager of VS, as shown in:

650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/20002152H-1.jpg "title =" 2.jpg" alt = "210658121.jpg"/>


Except NativeClass. I added the H file, and the others are projects, among which ManageClass. h and ManageClass. cpp is used to generate a dll. For the moment, ignore it. Let's take a look at NativeClass. content in h:

#pragma onceclass _declspec(dllexport) NativeClass{private:                                                                                                                                                                                                                                                                                                                                                                                                                              int nCount;public:    NativeClass(void)    {        this->nCount = 0;    }    ~NativeClass(void)    {    }    int GetCount(void)    {        return this->nCount;    }    void Increase(void)    {        this->nCount++;    }    void Clear(void)    {        this->nCount = 0;    }};


The content of the class is as simple as I can't bear to look directly at it. For example, the _ declspec (dllexport) field in the Class header is actually optional, but I am too lazy to delete it.


3. Content not hosted in C ++


This step is critical. The reason for this step is that the hosting of C ++ and non-hosting C ++ cannot be mixed, So I encapsulated the hosting code into the NativeClass class above, originally, in terms of specification, I should separate the function declaration and implementation, but I admit that I am also lazy, only in ManageClass. h, although ManageClass is not used. cpp, but do not delete the file anyway. Otherwise, the dll cannot be generated. My encapsulation code is as follows:

// ManageClass. h # pragma once # include "NativeClass. h" using namespace System; namespace ManageClass {public ref class NativeClassEx {// TODO: add this method here. 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 ;}};}


Don't tell me you didn't understand the above Code. I suggest you hit your head with a piece of tofu.


4. Generate a dll for hosting C ++


In fact, after this step is completed, you can directly compile and generate ManageClass In the Debug folder outside the project. after encapsulation, my new class name is NativeClassEx. Please pay attention to it when using it.


5. Project Test dll


Calling a dll hosted in C ++ is no different from calling a dll called in C #. I used a WinForm form project to create a test project. The name is DllTest, in Solution Explorer, replace the newly generated ManageClass. add the dll to the reference and use using ManageClass. Then you can use it. The test code is just a few words:

NativeClassEx testCalss = new NativeClassEx();Debug.WriteLine("GetCount : " + testCalss.GetCount().ToString());testCalss.Increase();testCalss.Increase();testCalss.Increase();Debug.WriteLine("GetCount : " + testCalss.GetCount().ToString());testCalss.Clear();Debug.WriteLine("GetCount : " + testCalss.GetCount().ToString());


Compile and check the output window. The class still runs perfectly.


Vi. Precautions


1. Although C # is highly compatible with hosted C ++, you should pay attention to alignment issues outside the basic types, such as struct and string classes, it is best to use the entry parameters other than the basic types. Please refer to the previous article;


2. I tried to encapsulate my OpenCV class with the hosted C ++, and then called the dll of OpenCV, that is, C #, to call the hosted dll and the hosted dll to call the unmanaged dll ), the compilation is successful, but the actual operation is not successful. It is unclear about any problems;


3. We recommend that you do not use this method to call classes. Calling dll Functions in C # is the most secure.


4. Download the sample project here. Compile the dll before using it and make sure that the reference is added. There may be some warning about the CPU type selection. Please be self-reliant.

This article from the "A few traces of rain lock clear autumn" blog, please be sure to keep this source http://joeyliu.blog.51cto.com/3647812/1297961

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.