一、什么是CLRc++
CLR(Common Language Runtime)是“公共语言运行时”的缩写,简单来讲它是和Java虚拟机同样的一个运行时环境。它负责资源管理(内存分配和垃圾收集),并保证应用和底层操做系统之间必要的分离。编程
通用语言运行时是.NET 框架应用程序的执行引挚。它提供了许多服务,其中包括:代码管理(装入和执行)、类型安全性验证、元数据(高级类型信息)访问、为管理对象管理内存、管理代码,COM对象和预生成的DLLs(非管理代码和数据)的交互操做性、对开发人员服务的支持等等。c#
咱们GOCW项目中为了可以使用Csharp调用OpenCV,采用了托管C++;数组
二、什么是托管C++?安全
托管是.NET的一个专门概念,它是融于通用语言运行时(CLR)中的一种新的编程理念,使用托管C++意味着,咱们的代码能够被CLR所管理,并能开发出具备最新特性如垃圾自动收集、程序间相互访问等的.NET框架应用程序。框架
由托管概念所引起的C++应用程序包括托管代码、托管数据和托管类三个组成部分。 ide
(1) 托管代码:. Net环境提供了许多核心的运行(RUNTIME)服务,好比异常处理和安全策略。为了能使用这些服务,必需要给运行环境提供一些信息代码(元数据),这种代码就是托管代码。全部的C#、VB.NET、JScript.NET默认时都是托管的,但Visual C++默认时不是托管的,必须在编译器中使用命令行选项(/CLR)才能产生托管代码。函数
(2) 托管数据:与托管代码密切相关的是托管数据。托管数据是由公共语言运行的垃圾回收器进行分配和释放的数据。默认状况下,C#、Visual Basic 和 JScript.NET 数据是托管数据。不过,经过使用特殊的关键字,C# 数据能够被标记为非托管数据。Visual C++数据在默认状况下是非托管数据,即便在使用 /CLR 开关时也不是托管的。编码
(3) 托管类: 尽管Visual C++数据在默认状况下是非托管数据,可是在使用C++的托管扩展时,可使用"__gc"关键字将类标记为托管类。就像该名称所显示的那样,它表示类实例的内存由垃圾回收器管理。另外,一个托管类也彻底能够成为 .NET 框架的成员,由此能够带来的好处是,它能够与其余语言编写的类正确地进行相互操做,如托管的C++类能够从Visual Basic类继承等。但同时也有一些限制,如托管类只能从一个基类继承等。须要说明的是,在托管C++应用程序中既可以使用托管类也可使用非托管类。这里的非托管类不是指标准C++类,而是使用托管C++语言中的__nogc关键字的类。spa
三、托管C++与标准C++的主要区别
尽管托管C++是从标准C++创建而来的,但它与标准C++有着本质上的区别,这主要体如今如下几个方面:
(1) 普遍采用"名称空间"(namespace)
名称空间是类型的一种逻辑命名方案,.NET使用该命名方案用于将类型按相关功能的逻辑类别进行分组,利用名称空间可使开发人员更容易在代码中浏览和引用类型。固然,咱们也可将名称空间理解成是一个"类库名"。
(2) 基本数据类型的变化
咱们知道,标准C++语言的数据类型是很是丰富的。而托管C++的数据类型更加丰富,不只包含了标准C++中的数据类型,并且新增了__int64 (64位整型)、Decimal(96位十进制数)、String*(字符串类型)和Object*(对象类型)等类型,表1-1列出它们各自数据类型。
(3) 新增三个托管C++类型:__gc class、__value class和__gc interface
一个__gc类或结构意味着该类或结构的生命周期是由.NET开发平台自动管理及垃圾自动收集,用户没必要自已去调用delete来删除。定义一个__gc类或结构和标准C++基本类似,所不一样的是在class或struct前加上__gc。
////////将输入cli::array<unsigned char>转换为cv::Mat//////////////////
pin_ptr
<System
:
:Byte
> p1
=
&pCBuf1[
0];
unsigned
char
* pby1
= p1;
cv
:
:Mat img_data1(pCBuf1
-
>Length,
1,CV_8U,pby1);
cv
:
:Mat img_object
= cv
:
:imdecode(img_data1,IMREAD_UNCHANGED);
if (
!img_object.data)
return nullptr;
System
:
:Drawing
:
:Bitmap
^ MatToBitmap(
const cv
:
:Mat
& img)
{
if (img.type()
!= CV_8UC3)
{
throw gcnew NotSupportedException(
"Only images of type CV_8UC3 are supported for conversion to Bitmap");
}
//create the bitmap and get the pointer to the data
PixelFormat fmt(PixelFormat
:
:Format24bppRgb);
Bitmap
^bmpimg
= gcnew Bitmap(img.cols, img.rows, fmt);
BitmapData
^data
= bmpimg
-
>LockBits(System
:
:Drawing
:
:Rectangle(
0,
0, img.cols, img.rows), ImageLockMode
:
:WriteOnly, fmt);
Byte
*dstData
=
reinterpret_cast
<Byte
*
>(data
-
>Scan0.ToPointer());
unsigned
char
*srcData
= img.data;
for (
int row
=
0; row
< data
-
>Height;
++row)
{
memcpy(
reinterpret_cast
<
void
*
>(
&dstData[row
*data
-
>Stride]),
reinterpret_cast
<
void
*
>(
&srcData[row
*img.step]), img.cols
*img.channels());
}
bmpimg
-
>UnlockBits(data);
return bmpimg;
}
具体关系见下图:
//2.引用传递int
int GOClrClass
:
:allTest(
int a,
int b,
int
* c);
int GOClrClass
:
:allTest(
int a,
int b,
int
* c)
{
*c
=a
+b;
return
*c;
}
unsafe
{
int
* value
= stackalloc
int[
1];
value[
0]
=
0;
int iret
= client.allTest(
2,
3, value);
}
System
:
:String
^ GOClrClass
:
:allTestStr(System
:
:String
^ inputStr)
{
System
:
:String
^ retstr
=
"fsdfsdf";
return retstr;
}
string
s
=
client
.
allTestStr
(
"abcdefg"
);