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 + + class in Managed C + + for use in C #.
For example, there is now a DLL written by C + + with the project named Nativecppdll, 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)#endif//hovertree.comclassLx_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 typical DLL developed by C + +, outputting 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 the required C + + classes are large, or many 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 is to encapsulate the C + + class with managed C + + and then provide it to C # for use. The following code is used to describe in detail how to encapsulate the C + + class with managed C + +.
First, create a managed C + + DLL project Managecppdll, and 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(); }//hovertree.comProperty 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; };};
As you can see from this header file, this is the wrapper for C + + class CPerson. All public member functions of the class person are the same as the C + + class CPerson, except that the parameters and return values of the member functions are changed to the managed C + + type, which is the first condition for the 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 + + hovertree.compin_ptr<ConstWchar_t> Wcname =PtrToStringChars (strName); M_pimp=NewCPerson (Wcname, Csex, iage); } Person::~Person () {//Deleting a CPerson object in a destructor DeleteM_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:
Usingnew "Starlee" ' M ' ; // How to ask
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 a bridge pattern, 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.
http://www.cnblogs.com/roucheng/
Http://www.cnblogs.com/roucheng/p/3521864.html
C # Reference C + + code