.net中 CLI/C++中混合类的使用[CAutoNativePtr智能指针]


一 混合类

所谓混合类是指CLI/C++中native的Class中可以包含CLR对象,CLR的class也可以包含Naitve的对象。

1)native的class中包含CLR对象,必须通过gcroot<>或auto_gcroot<>。
2)CLR中的class中包含native的对象,必须是指针,也可以使用高手写的CAutoNativePtr智能指针。


注意:C#中不能调用CLI/C++中的Native的class。同样Native C++中也不能调用CLI/C++中的Ref的class。

二 实例

 高手的CAutoNativePtr类:

/***
    CAutoNativePtr - A smart pointer for using native objects in managed code.

    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++文件:
//  MixedNativeAndCLIDLL.h

#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;
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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值