=================================版權聲明=================================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可調用包裝器
這個書不怎麼講這部分。
=======================================================================
大致看完了,有空仔細研讀擴展。作作小東西。