一 混合类
所谓混合类是指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类:

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
- c语言入门-03-数据和c
1>C语言提供两大系列的多种数据类型 1 /*platinum.c*/ 2 #include <stdio.h> 3 4 int main(void){ 5 float weight ...
- 07 JVM 是如何实现反射的
Java 中的反射 反射是 Java 语言的一个相当重要的特性,它允许正在运行的 Java 程序观测,甚至是修改程序的动态行为. 我们可以通过 Class 对象枚举该类中的所有方法,还可以通过 Met ...
- astyle使用基础教程
astyle使用基础教程 转自: http://babybandf.blog.163.com/blog/static/61993532010112205811797/ astyle是一个我自己常用的开 ...
- 重做LVM文件系统之减小PV
命令 缩小PV空间到120G,即PV上的vg00已将缩小到120G pvresize --setphysicalvolumesize 120g /dev/sda2 背景 机器上有一块900G本地的本地 ...
- wewe
<#assign base=rc.contextPath /> <#import "spring.ftl" as s /> <!DOCTYPE htm ...
- 【16】vuex2.0 之 getter
有的组件中获取到 store 中的state, 需要对进行加工才能使用,computed 属性中就需要写操作函数,如果有多个组件中都需要进行这个操作,那么在各个组件中都写相同的函数,那就非常麻烦,这 ...
- HDU 4487 Maximum Random Walk
Maximum Random Walk Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- sublime 中设置pylint
http://www.360doc.com/content/14/1110/11/15077656_424004081.shtml 安装 pylinter 插件 详见 sublime 插件安装 配 ...
- js遍历函数
function each(arr, callback, thisp) { if (arr.forEach) {arr.forEach(callback, thisp);} else { for (v ...
- springBoot AOP环绕增强、自定义注解、log4j2、MDC
(一)log4j2 maven配置 <dependency> <groupId>org.springframework.boot</groupId> <art ...