C++/CLI——讀書筆記《Visual C++/CLI從入門到精通》 第Ⅳ部分

=================================版權聲明=================================html

版權聲明:本文爲博主原創文章 未經許可不得轉載 
ios

請經過右側公告中的「聯繫郵箱(wlsandwho@foxmail.com)」聯繫我安全

未經做者受權勿用於學術性引用。app

未經做者受權勿用於商業出版、商業印刷、商業引用以及其餘商業用途。                    函數

 

本文不按期修正完善,爲保證內容正確,建議移步原文處閱讀。                                                               <--------總有一天我要本身作一個模板幹掉這隻土豆
佈局

本文連接:優化

恥辱牆:http://www.cnblogs.com/wlsandwho/p/4206472.htmlui

=======================================================================spa

 第二十二章 使用非託管代碼設計

  System::Runtime::InteropServices

  GCHandle

    GCHandle::Alloc

    GCHandle::Free

  gcroot輔助模板類

    代替對GCHandle的直接操做

    離開做用域時銷燬

  auto_gcroot

    <auto_gcroot.h>

    離開做用域時調用析構函數

  混合類

    託管類中添加指向非託管對象的指針成員

      須要爲託管類聲明析構函數

      ref Classs ManagedClass

      {

      public:

        ~ManagedClass(){delete m_pUnc;}

      private:

        UnManagedClass* m_pUnC;

      }

    非託管類中添加託管類

      Class UnManagedClass

      {

      public:

        UnManagedClass(gcroot<ManagedClass^> gcrMC):m_gcrMC(gcrMC){}

      private:

        gcroot<ManagedClass^> m_gcrMC;

      }

 1 #include "stdafx.h"
 2 #include <gcroot.h>
 3 #include <iostream>
 4 #include <atlstr.h>
 5 
 6 using namespace System;
 7 using namespace System::Runtime::InteropServices;
 8 ref class CPerson
 9 {
10 public:
11     CPerson(int nAge, String^ strName) :m_nAge(nAge),m_strName(strName) {}
12 
13     int GetAge() { return m_nAge; }
14     String^ GetName() { return m_strName; }
15 
16 private:
17     int m_nAge;
18     String ^ m_strName;
19 };
20 
21 class CPersonInfo
22 {
23 public:
24     CPersonInfo(gcroot<CPerson^> gcroPerson):m_oPerson(gcroPerson){}
25     int GetAge() { return m_oPerson->GetAge(); }
26     CString GetName() 
27     {
28         return m_oPerson->GetName(); 
29     }
30 
31 private:
32     gcroot<CPerson^> m_oPerson;
33 };
34 
35 int main(array<System::String ^> ^args)
36 {
37     CPerson^ oPerson = gcnew CPerson(11, L"Jack");
38     CPersonInfo oPersonInfo(oPerson);
39 
40     std::wcout << oPersonInfo.GetName().GetString() << L"    " << oPersonInfo.GetAge() <<std::endl;
41 
42     return 0;
43 }

   固定指針

    值不變的託管對象指針

    垃圾回收器不能移動它

    能夠安全的傳給非託管對象

    固定託管對象的成員形成整個託管對象都被固定

    只要存在對固定指針的引用,託管對象就會一直被固定

 1 #include "stdafx.h"
 2 #include <iostream>
 3 using namespace System;
 4 
 5 void PrintANumber(int * pNumArr)
 6 {
 7     std::cout << *pNumArr << std::endl;
 8 }
 9 
10 int main(array<System::String ^> ^args)
11 {
12     array<int>^ arrNum = gcnew array<int>{11, 22, 33, 44, 55};
13 
14     pin_ptr<int> pinNumArr = &arrNum[2];
15 
16     PrintANumber(pinNumArr);
17 
18     pinNumArr = nullptr;
19 
20     return 0;
21 }

  dynamic_cast不匹配時返回null

  safe_cast不匹配時拋出異常

  包裝了簡單值的任何東西,只要大小不超過16字節就是和設計成值類型。

  裝箱

    C++/CLI自動裝箱

    裝箱會發生值類型的按位拷貝

  拆箱

    經過強制類型轉換

    safe_cast<>()

 1 #include "stdafx.h"
 2 
 3 using namespace System;
 4 
 5 
 6 int main(array<System::String ^> ^args)
 7 {
 8     int nNum = 12;
 9     Console::WriteLine(nNum);
10 
11     Object^ obj12 = nNum;
12     Console::WriteLine(obj12);
13 
14     int nNum12 = safe_cast<int>(obj12);
15     Console::WriteLine(nNum12);
16 
17     return 0;
18 }

   P/Invoke

    封送  在託管代碼和非託管代碼之間傳遞數據/在託管代碼和非託管代碼之間自動轉換 

#include "stdafx.h"                                                                
                                                                                   
using namespace System;                                                            
                                                                                   
using namespace System::Runtime::InteropServices;                                  
                                                                                   
[DllImport("User32.dll",CharSet=CharSet::Auto)]                                    
                                                                                   
//int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType )       
int MessageBox(IntPtr hWnd, String^ lpText, String^ lpCaption, unsigned int uType);
                                                                                   
int main(array<System::String ^> ^args)                                            
{                                                                                  
   // Console::WriteLine(L"Hello World");                                          
	String^ strText = L"Text";                                                        
	String^ strCaption = L"Caption";                                                  
	MessageBox(IntPtr::Zero, strText, strCaption,0);                                  
                                                                                   
    return 0;                                                                      
}                                                                                  
#include "stdafx.h"

using namespace System;

using namespace System::Runtime::InteropServices;

[DllImport("User32.dll", EntryPoint="MessageBox",CharSet = CharSet::Auto)]

//int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType )
int ShowSomething(IntPtr hWnd, String^ lpText, String^ lpCaption, unsigned int uType);

int main(array<System::String ^> ^args)
{
	// Console::WriteLine(L"Hello World");
	String^ strText = L"Text";
	String^ strCaption = L"Caption";
	ShowSomething(IntPtr::Zero, strText, strCaption, 0);

	return 0;
}

  傳遞結構

    佈局

      自動佈局LayoutKind::Auto  讓運行時優化佈局 P/Invoke時不要用

      顯式佈局LayoutKind::Explicit  按定製的字節偏移量排列

      順序佈局LayoutKind::Sequential  託管和非託管一樣的排列

#include "stdafx.h"

using namespace System;

using namespace System::Runtime::InteropServices;

[StructLayoutAttribute(LayoutKind::Sequential)]
ref class CPowerState
{
public:
	System::Byte ACLineStatus;
	System::Byte BatteryFlag;
	System::Byte BatteryLifePercent;
	System::Byte ReservedforNow;
	System::UInt32 BatteryLifeTime;
	System::UInt32 BatteryFullLifeTime;
};

typedef long BOOL;

[DllImportAttribute("Kernel32.dll")]
BOOL GetSystemPowerStatus(CPowerState^ PS);

int main(array<System::String ^> ^args)
{
   // Console::WriteLine(L"Hello World");
	CPowerState^ oPS=gcnew CPowerState();
	BOOL bRet=GetSystemPowerStatus(oPS);

    return 0;
}

=======================================================================

 第二十三章 特性和反射

   元數據

    不知道在說什麼

  使用預約義特性類

 1 #pragma once
 2 
 3 using namespace System;
 4 
 5 namespace MyDll {
 6 
 7     public ref class CTestClass
 8     {
 9         // TODO:  在此處添加此類的方法。
10     public:
11         CTestClass(int nVal):m_nVal(nVal){}
12 
13         [ObsoleteAttribute("Use the Var Property instead",false)]
14         int GetVal() { return m_nVal; }
15         
16         property int Val
17         {
18             int get() { return m_nVal; }
19         }
20 
21     private:
22         int m_nVal;
23 
24     };
25 }
 1 using namespace System;
 2 
 3 using namespace MyDll;
 4 
 5 int main(array<System::String ^> ^args)
 6 {
 7     CTestClass^ oTC = gcnew CTestClass(666);
 8     int nVal = oTC->GetVal();
 9     Console::WriteLine(L"{0}",nVal);
10 
11     return 0;
12 }

   定義本身的特性

    特性類

      定位參數  必選參數  只讀屬性

      具名參數  可選參數  讀寫屬性

    

 1 // CustomAttributes.h
 2 
 3 #pragma once
 4 
 5 using namespace System;
 6 
 7 namespace CustomAttributes {
 8 
 9     [AttributeUsageAttribute(AttributeTargets::Method|AttributeTargets::Property| AttributeTargets::Class)]
10     public ref class DocumentationAttributes:Attribute 
11     {
12         // TODO:  在此處添加此類的方法。
13     public:
14         DocumentationAttributes(String^ strText):m_strText(strText) {};
15         
16         property String^ Text
17         {
18             String^ get(){return m_strText;}
19         }
20 
21         property String^ Author
22         {
23             String^ get() { return m_strAuthor; }
24             void set(String^ strAuthor) { m_strAuthor=strAuthor; }
25         }
26         property String^ Date
27         {
28             String^ get() { return m_strDate; }
29             void set(String^ strDate) { m_strDate = strDate; }
30         }
31 
32     private:
33         String^ m_strText;
34         String^ m_strAuthor;
35         String^ m_strDate;
36     };
37 }
 1 #include "stdafx.h"
 2 
 3 using namespace System;
 4 
 5 using namespace CustomAttributes;
 6 
 7 [DocumentationAttributes("The TestAttrs class",Author="WLS")]
 8 ref class TestAttrs
 9 {
10 public:
11     [DocumentationAttributes("The TestAttrs class constructor takes an integer",Author="WLS",Date="2010/01/02")]
12     TestAttrs(int nV)
13     {
14         m_nVal = nV;
15     }
16 
17     [DocumentationAttributes("The read-only Value property returns the value of the int class number", Author = "WLS")]
18     property int Value
19     {
20         int get() { return m_nVal; }
21     }
22 
23 protected:
24 private:
25     int m_nVal;
26 };
27 
28 int main(array<System::String ^> ^args)
29 {
30     Console::WriteLine(L"Hello World");
31     return 0;
32 }

   反射

    不知爲什麼感受少了點什麼編譯不經過

    並且對於C++/CLI來講,這個東西主要是用來支持別的語言吧?

 1 // UseAttributes.cpp: 主項目文件。
 2 
 3 #include "stdafx.h"
 4 
 5 
 6 using namespace System;
 7 
 8 using namespace MyDll;
 9 
10 using namespace::Reflection;
11 
12 int main(array<System::String ^> ^args)
13 {
14     CTestClass^ oTC = gcnew CTestClass(666);
15     int nVal = oTC->GetVal();
16 
17     Type^ t = oTC->GetType();
18     array<Object^>^ atts=t->GetCustomAttributes(true);
19     
20     array<MemberInfo^>^ mi = t->GetMembers();
21 
22     for each(MemberInfo^ m in mi)
23     {
24         array<Object^>^ a = m->GetCustomAttributes(true);
25 
26         if (a->Length>0)
27         {
28             Console::WriteLine("Attributes for member {0}", m->Name);
29             for each (Object^ attr in a)
30             {
31                 Console::WriteLine("attribute is {0}", attr->ToString());
32 
33                 //DocumentationAttribute^ Da = dynamic_cast<DocumentationAttribute^>(attr);
34 
35             }
36         }
37     }
38 
39     Console::WriteLine(L"{0}",nVal);
40 
41     return 0;
42 }

 

 =======================================================================

 第二十四章 兼容COM

  在.NET中使用COM

    RCW  運行時可調用包裝器  封送  使用時無差異感覺

 1 // ComWrapper.cpp: 主項目文件。
 2 
 3 #include "stdafx.h"
 4 
 5 using namespace System;
 6 
 7 using namespace TempConverterLib;
 8 
 9 int main(array<System::String ^> ^args)
10 {
11     Console::WriteLine(L"Hello World");
12 
13     TempConverterLib::ConverterClass^ conv= gcnew TempConverterLib::ConverterClass();
14     
15     double dF = conv->ConvertC2F(27.0);
16     
17     Console::WriteLine("27C is {0} F", dF);
18 
19     try
20     {
21         double dF = conv->ConvertC2F(-280.0); 
22           
23         Console::WriteLine("-280C is {0} F", dF);
24     }
25     catch (Exception^ e)
26     {
27         Console::WriteLine("Exception  from COM object:{0}", e->Message);
28     }
29 
30     return 0;
31 }

 

  晚期綁定

 1 // LateBind.cpp: 主項目文件。
 2 
 3 #include "stdafx.h"
 4 
 5 using namespace System;
 6 
 7 int main(array<System::String ^> ^args)
 8 {
 9     Guid g = Guid("75F3EDC5-AA71-437A-ACB6-F885C29E50F7");
10 
11     Type^ t = Type::GetTypeFromCLSID(g);
12 
13     if (t==nullptr)
14     {
15         Console::WriteLine("1");
16     }
17 
18     Object^ obj = System::Activator::CreateInstance(t);
19 
20     array<Object^>^ argarray = { 27.0 };
21 
22     try
23     {
24         Object^ result = t->InvokeMember("ConvertC2F", Reflection::BindingFlags::InvokeMethod, nullptr, obj, argarray);
25 
26         double dF = Convert::ToDouble(result);
27 
28         Console::WriteLine("27C is {0}F", dF);
29     }
30     catch (Exception^ e)
31     {
32         Console::WriteLine("2");
33     }
34 
35     return 0;
36 }

 

   把.NET做爲COM組件使用

    CCW  COM可調用包裝器

    這個書不怎麼講這部分。

=======================================================================

大致看完了,有空仔細研讀擴展。作作小東西。

相關文章
相關標籤/搜索