Now the application development under Windows, VS. NET occupies the majority of the share. So many people who used to develop VC + + have turned to use more powerful vs.net. In this case, there are many developers who are faced with the problem of how to use C + + to develop good classes in C #. Here is a complete example of how to encapsulate a C + + with managed C + +class to provide for use in C #. For example, there is now a project named Nativecppdll by C++written DLL, which outputs a CPerson class. Here is the specific code://NativeCppDll.h#pragmaOnce#ifndef lx_dll_class_exports#defineLx_dll_class __declspec (dllexport)#else #defineLx_dll_class __declspec (dllimport)#endifclassLx_dll_class cperson{ Public: CPerson (); CPerson (Constwchar_t *pname,Constwchar_t Csex,intiage); voidSetName (Constwchar_t *pName); wchar_t*GetName (); voidSetsex (Constwchar_t csex); wchar_t Getsex (); voidSetage (intiage); intGetage (); wchar_t*GetLastError ();Private: wchar_t m_szname[ -]; wchar_t M_csex; intM_iage; wchar_t m_szlasterror[ -]; voidshowerror ();};//NativeCppDll.cpp#include"stdafx.h"#include"NativeCppDll.h"#include<iostream>#include<tchar.h>using namespacestd; Cperson::cperson () {wcscpy_s (M_szname, _t ("No Name")); M_csex='N'; M_iage=0; wcscpy_s (M_szlasterror, _t ("No Error"));} Cperson::cperson (Constwchar_t *pname,Constwchar_t Csex,intiage) {wcscpy_s (M_szlasterror, _t ("No Error")); SetName (PName); Setsex (Csex); Setage (iage);}voidCperson::setname (Constwchar_t *pName) { if((PName = = NULL) | | (Wcslen (pName) = =0) || (Wcslen (PName) >127) {wcscpy_s (M_szname, _t ("No Name")); wcscpy_s (M_szlasterror, _t ("The length of the input name is an out of range.")); ShowError (); return; } wcscpy_s (M_szname, pName);} wchar_t*Cperson::getname () {returnM_szname;}voidCperson::setsex (Constwchar_t Csex) { if((Csex! ='F') && (Csex! ='M') && (Csex! ='m') && (Csex! ='F') ) {M_csex='N'; wcscpy_s (M_szlasterror, _t ("The input sex is out of [f/m].")); ShowError (); return; } m_csex=Csex;} wchar_t Cperson::getsex () {returnM_csex;}voidCperson::setage (intiage) { if((Iage <0) || (Iage > Max) ) {M_iage=0; wcscpy_s (M_szlasterror, _t ("The input is an out of range.")); ShowError (); return; } m_iage=iage;}intCperson::getage () {returnM_iage;} wchar_t*Cperson::getlasterror () {returnM_szlasterror;}voidCperson::showerror () {Cerr<< M_szlasterror <<Endl;} This is a very typical by C+ + developed DLL, output a complete C + + class. What if you need to develop a C # project now and use the C + + class CPerson output from this DLL? For this example, class CPerson is very small and can be used to re-write a class like this C + + class in C #. However, if you need the C + +class is large, or a lot of times, rewriting works will be very large. And it's not reusing existing code, wasting existing resources, and creating time-consuming and laborious development. Of course, there are ways to solve this problem. That's using managed C+ + encapsulates the C + + class and then provides it to C # for use. Here's a code to detail how to use managed C + + to encapsulate the above C + +class. First, you want to create a managed C++DLL Engineering Managecppdll, and then add the following code inside://ManageCppDll.h#pragmaOnce#defineLx_dll_class_exports#include".. /nativecppdll/nativecppdll.h"using namespaceSystem;namespaceManagecppdll { Public ref classPerson {//wrapper public member functions for all class CPerson Public: Person (); Person (String^ StrName, Char csex,intiage); ~Person (); Property String^Name {void Set(String ^strName); String^Get(); } Property Char Sex {void Set(Char csex); CharGet(); } PropertyintAge {void Set(intiage); int Get(); } String^GetLastError (); Private: //a pointer to the class CPerson that invokes the member function of the class CPersonCPerson *M_pimp; };}; From this header file you can see that this is the C+ + class CPerson packaging. All public member functions of the class person are the same as the C + + class CPerson, except that the parameter and return value of the member function is changed to managed C + +type, which is the first condition that allows a class person to be used in C #. Of course, only the public member functions need to be encapsulated, and no encapsulation is necessary for the protection of member functions and private member functions. The class person has only one private member variable: A pointer to a class CPerson. The implementation of all member functions of the class person is accomplished by invoking the corresponding member function of the class CPerson by this cperson pointer. Here is the specific implementation code://ManageCppDll.cpp#include"stdafx.h"#include"ManageCppDll.h"#include<vcclr.h>namespaceManagecppdll {//creates an object of class CPerson in the constructor and destroys the object in the destructor//all member function implementations are implemented by invoking the corresponding member function of the class CPerson by pointer m_pimpPerson ::P Erson () {M_pimp=NewCPerson (); } Person::P Erson (String^ StrName, Char csex,intiage) { //converts a string to a pointer that is recognized by C + +pin_ptr<ConstWchar_t> Wcname =PtrToStringChars (strName); M_pimp=NewCPerson (Wcname, Csex, iage); } Person::~Person () {//Deleting a CPerson object in a destructorDelete m_pimp; } voidPerson::name::Set(String ^strName) {pin_ptr<ConstWchar_t> Wcname =PtrToStringChars (strName); M_pimp-SetName (wcname); } String^ Person::name::Get() { returnGcnew String (m_pimp->GetName ()); } voidPerson::sex::Set(Char csex) {m_pimp-Setsex (csex); } Char person::sex::Get() { returnM_pimp->Getsex (); } voidPerson::age::Set(intiage) {M_pimp-setage (iage); } intPerson::age::Get() { returnM_pimp->Getage (); } String^Person::getlasterror () {returnGcnew String (m_pimp->GetLastError ()); }}; If you want to use class person in C #, first add a reference to ManageCppDll.dll, and then you can use the class person as you would with a normal C # class. such as the following code:usingManagecppdll; Person Person=NewPerson ();p Erson. Name="Starlee";p Erson. Sex='M';p Erson. Age= -; Familiar with the design pattern to see the above code will certainly find that this design is the same as bridge mode. In fact, the above method is also considered a bridge mode, by the managed C+ + serves as a bridge for C # to use classes developed in C + +. In addition, this form can also be understood as adapter mode, managed C + + class person is the C + + class CPerson an adapter. With this bridge, it is easy to reuse classes that were previously developed in C + +, so that these C + + classes continue to play their role in C #, making development more effective.
Classes written in C # using C + +