CLI/C++中混合類的使用【轉】

http://www.cppblog.com/mzty/archive/2007/12/24/39517.html

CLI/C++中混合類的使用


一 混合類

所謂混合類是指CLI/C++中native的Class中能夠包含CLR對象,CLR的class也能夠包含Naitve的對象。html

1)native的class中包含CLR對象,必須經過gcroot<>或auto_gcroot<>。
2)CLR中的class中包含native的對象,必須是指針,也可使用高手寫的CAutoNativePtr智能指針。ios


注意:C#中不能調用CLI/C++中的Native的class。一樣Native C++中也不能調用CLI/C++中的Ref的class。

二 實例

 高手的CAutoNativePtr類:express


    Author    :    Nishant Sivakumar
    Email    :    voidnish@gmail.com    
    Blog    :     http://blog.voidnish.com
    Web        :    http://www.voidnish.com     

    You may freely use this class as long as you include
    this copyright. 
    
    You may freely modify and use this class as long
    as you include this copyright in your modified version. 

    This code is provided "as is" without express or implied warranty. 
    
    Copyright ?Nishant Sivakumar, 2006.
    All Rights Reserved.
***/

#pragma once

template<typename T> ref class CAutoNativePtr
{
private:
    T* _ptr;

public:
    CAutoNativePtr() : _ptr(nullptr)
    {
    }

    CAutoNativePtr(T* t) : _ptr(t)
    {
    }

    CAutoNativePtr(CAutoNativePtr<T>% an) : _ptr(an.Detach())
    {
    }

    template<typename TDERIVED> 
        CAutoNativePtr(CAutoNativePtr<TDERIVED>% an) : _ptr(an.Detach())
    {
    }

    !CAutoNativePtr()
    {    
        delete _ptr;
    }

    ~CAutoNativePtr()
    {
        this->!CAutoNativePtr();
    }

    CAutoNativePtr<T>% operator=(T* t)
    {
        Attach(t);
        return *this;
    }

    CAutoNativePtr<T>% operator=(CAutoNativePtr<T>% an)
    {
        if(this != %an)
            Attach(an.Detach());
        return *this;
    }

    template<typename TDERIVED> 
        CAutoNativePtr<T>% operator=(CAutoNativePtr<TDERIVED>% an)
    {
        Attach(an.Detach());
        return *this;
    }

    static T* operator->(CAutoNativePtr<T>% an)
    {
        return an._ptr;
    }

    static operator T*(CAutoNativePtr<T>% an)
    {
        return an._ptr;
    }

    T* Detach()
    {
        T* t = _ptr;
        _ptr = nullptr;
        return t;
    }

    void Attach(T* t)
    {
        if(t)
        {    
            if(_ptr != t)
            {
                delete _ptr;
                _ptr = t;
            }
        }
        else        {#ifdef _DEBUG            throw gcnew Exception(                "Attempting to Attach() a nullptr!");#endif        }            }    void Destroy()    {        delete _ptr;        _ptr = nullptr;    }};

測試實例之CLI/C++文件:


#pragma once
#include <string>
#include <iostream>
#include <gcroot.h>
#include <msclr/auto_gcroot.h>

#include "AutoNative.h"

using namespace System;

namespace MixedNativeAndCLIDLL {

    public class NativeClass
    {
    public:
        int *pX;    
        NativeClass(){pX = new int(10);}
        ~NativeClass()
        {
            if(pX != NULL)
            {
                delete pX;
                pX = NULL;
            }
        }        
    };

    public ref class RefClass
    {
    public:
        int x;    
        RefClass(){x = 20;}
    };

    public class MixedClass0
    {
        public:
            NativeClass nativeClass;
            //RefClass refClass; // error c3265 and error c3149
            gcroot<RefClass^> refClass1;

            std::string nativeStr;
            //System::String refStr; // error c3265 and error c3149
            gcroot<System::String^> refStr1;

            MixedClass0()
            {
                refClass1 = gcnew RefClass();
                refStr1 = gcnew System::String("i am a native class mixed some clr members.\n");
            }
            ~MixedClass0()
            {            
                delete refClass1;
                delete refStr1;
            }

            void PrintSelf()
            {
                System::Console::WriteLine("my name is MixedClass0");
                System::Console::WriteLine(refClass1->x);
                System::Console::WriteLine(refStr1);
            }
    };

    public class MixedClass1
    {
        public:
            NativeClass nativeClass;
            //RefClass refClass; // error c3265 and error c3149
            msclr::auto_gcroot<RefClass^> refClass1;

            std::string nativeStr;
            //System::String refStr; // error c3265 and error c3149
            msclr::auto_gcroot<System::String^> refStr1;

            MixedClass1()
            {
                refClass1 = gcnew RefClass();
                refStr1 = gcnew System::String("i am a native class with some clr members.\n");
            }
            ~MixedClass1()
            {
                // no need to delete.            }                    void PrintSelf()            {                System::Console::WriteLine("my name is MixedClass1");                System::Console::WriteLine(refClass1->x);                System::Console::WriteLine(refStr1);            }    };    public ref class MixedClass2    {        public:            //NativeClass nativeClass; // error c4368            NativeClass * nativeClass1;            RefClass^ refClass;                         //std::string nativeStr; // error c4368            std::string *nativeStr1;            System::String^ refStr; //                 MixedClass2()            {                nativeClass1 = new NativeClass();                nativeStr1 = new std::string("i am a clr class with some native members.\n");            }            ~MixedClass2()            {                delete nativeClass1;                delete nativeStr1;            }            !MixedClass2(){}            void PrintSelf()            {                System::Console::WriteLine("my name is MixedClass2");                std::cout<<*(nativeClass1->pX)<<std::endl;                std::cout<<*nativeStr1<<std::endl;                            }    };        public ref class MixedClass3    {        public:            //NativeClass nativeClass; // error c4368            CAutoNativePtr<NativeClass> nativeClass1;            RefClass^ refClass;                         //std::string nativeStr; // error c4368            CAutoNativePtr<std::string> nativeStr1;            System::String^ refStr; //                 MixedClass3()            {                nativeClass1 = new NativeClass();                nativeStr1 = new std::string("i am a clr class with some native members.\n");            }            ~MixedClass3(){}            !MixedClass3(){}            void PrintSelf()            {                System::Console::WriteLine("my name is MixedClass3");                std::cout<<*(nativeClass1->pX)<<std::endl;                std::cout<<*nativeStr1<<std::endl;                            }    };}

測試實例之C#調用文件:
using System.Collections.Generic;
using System.Text;

namespace CsharpTest
{
    class Program
    {
        static void Main(string[] args)
        {
            MixedNativeAndCLIDLL.MixedClass0 mixedClass0 = new MixedNativeAndCLIDLL.MixedClass0();
            //mixedClass0.PrintSelf();
            MixedNativeAndCLIDLL.MixedClass1 mixedClass1 = new MixedNativeAndCLIDLL.MixedClass1();
            //mixedClass1.PrintSelf();
            MixedNativeAndCLIDLL.MixedClass2 mixedClass2 = new MixedNativeAndCLIDLL.MixedClass2();
            mixedClass2.PrintSelf();
            MixedNativeAndCLIDLL.MixedClass3 mixedClass3 = new MixedNativeAndCLIDLL.MixedClass3();
            mixedClass3.PrintSelf();
        }
    }
}

三 代碼下載

http://www.cppblog.com/Files/mzty/MixedNativeAndCLITest.rar
相關文章
相關標籤/搜索