德陽哪里有做網(wǎng)站的windows優(yōu)化大師是官方的嗎
C++/CLI——1簡介
如果你是.net程序員,不免會(huì)用到C++/C寫的庫。對(duì)于簡單的調(diào)用,可以直接使用DllImport來完成就可以,詳情可參考C#調(diào)用C/C++從零深入講解。但是對(duì)于復(fù)雜的C++類和對(duì)象,尤其是類似于OCC的大型C++項(xiàng)目,DllImport可能不夠方便,這就要引出C++/CLI方式來實(shí)現(xiàn)C#與C++/C庫的交互。C++/CLI常用的5中場(chǎng)景有:
- 在.net中靜態(tài)調(diào)用WindowApi或者DLL。
通常可經(jīng)過 DllImport 屬性包裝出函數(shù)來調(diào)用
- 用托管C++包裝現(xiàn)有的DLL,供C#調(diào)用
托管C++代碼可以直接引用原有的頭文件,直接調(diào)用非托管函數(shù),而不需要聲明。這樣,既減少了工作量,又避免引入錯(cuò)誤。缺點(diǎn)是,這種方法會(huì)增加一個(gè)DLL。要注意的是托管字符串和非托管字符串是有區(qū)別的,并需要轉(zhuǎn)換(特別要注意的Unicode字符串和多字節(jié)字符串的轉(zhuǎn)換)。
- 現(xiàn)有C++源代碼,包裝后供C#調(diào)用
C++的源代碼,實(shí)際上可以直接編譯成托管代碼
- 在托管C++代碼中混合托管和非托管代碼
只要從#pragma unmanaged編譯指示開始的程序,一率編譯成非托管代碼;要想恢復(fù)成托管代碼,只要使用#pragma managed就可以了
-
不要DLL,直接把C++源代碼與C#源代碼一起編譯成一個(gè)單獨(dú)的Assembly
聲明類
ref class Animal
{
public:int legs;void SetName(String^ name){this->name = name;}String^ GetName(){return name;}
private:String^ name;
};
- 聲明類時(shí),加上了
ref
關(guān)鍵字,該類就變成了托管類,是可以被gc來管理的。加上了ref的類被稱為引用類型
,這是由于變量不實(shí)際包含對(duì)象,而是包含指向?qū)ο髢?nèi)存位置的指針,也可以稱之為句柄
,引用對(duì)象必須分配在堆上。 - 可以使用
value
關(guān)鍵字來聲明類,此時(shí)該類便是值類型,直接分配在棧上,變量本身包含對(duì)象本身。
#include "pch.h"
using namespace System;ref class AnimalRef
{
public:int legs;void SetName(String^ name){this->name = name;}String^ GetName(){return name;}
private:String^ name;};value class AnimalValue
{
public:int legs;void SetName(String^ name){this->name = name;}String^ GetName(){return name;}
private:String^ name;};int main(array<System::String^>^ args)
{AnimalRef cat;cat.SetName("mm");cat.legs = 4;Console::Write("cat:");Console::WriteLine(cat.GetName());AnimalValue dog;dog.SetName("xx");dog.legs = 4;Console::Write("dog:");Console::WriteLine(dog.GetName());Console::WriteLine(sizeof(dog));return 0;
}
基本數(shù)據(jù)類型
類型 | 說明 |
---|---|
bool | |
char,__int8 | 單字節(jié),一般用于容納ASCII |
short,__int16 | 整數(shù) |
int,__int32 | 整數(shù) |
long | 整數(shù),許多編譯器中是int的兩倍 |
long long ,__int64 | 整數(shù) |
float | 浮點(diǎn) |
double | 雙精度 |
wchar_t | 寬字符或多字符 |
在標(biāo)準(zhǔn)C++中,基本數(shù)據(jù)類的大小是不固定的,如int可能是4字節(jié),也可能是8,或者其他,這是根據(jù)運(yùn)行平臺(tái)來決定的,但是在c++/cli中基本數(shù)據(jù)類型的大小是固定的。
句柄和指針
在標(biāo)準(zhǔn)C++中,指針容納的是一個(gè)變量的內(nèi)存地址,通過指針可以間接引用變量,但是C++/cli中,運(yùn)行時(shí)會(huì)管理內(nèi)存,所以它會(huì)將內(nèi)存的東西一來一去以最大化的利用內(nèi)容空間,這就意味著對(duì)象不會(huì)總在一個(gè)位置待著,這時(shí)候,指針的地址會(huì)過期。所以C++/CLI中沒有指針的概念而是使用句柄
來包含變量的地址,運(yùn)行時(shí)會(huì)自動(dòng)更新這個(gè)地址。
聲明句柄的方式就是在變量名前面加上^
符號(hào),而且一般使用gcnew
操作符號(hào)來創(chuàng)建對(duì)象并獲取它的句柄。
int main(array<System::String^>^ args)
{AnimalValue^ cat = gcnew AnimalValue();cat->legs = 4;cat->SetName("mm");Console::WriteLine(cat->GetName());array<int>^ arr = gcnew array<int>(10);arr[0] = 12;Console::WriteLine(arr[0]);return 0;
}
強(qiáng)制類型轉(zhuǎn)換
可以使用以下幾種方式進(jìn)行類型轉(zhuǎn)換:
- (),例如:
(float)7
- static_cast<>:常用
- const_cast<>:配合指針使用,添加或刪除變量的常量限定
- dynamic_cast<>:在繼承層次中使用
- safe_cast<>:類似于dynamic_cast<>,轉(zhuǎn)換失敗會(huì)報(bào)異常
- reinterpret_cast<>:將指針轉(zhuǎn)換成其他類型指針
尖括號(hào)中是目標(biāo)類型
int a = 10;
double b;
b = static_cast<double>(a);