在Kernel Mode使用c++運算子new必須自已實做。--------------------------------------------------------------------------------------------------------------------------比較快的做法,限定為可分頁且不在memory上加Taginline void* __cdecl operator new(size_t Size) { KIRQL irql = KeGetCurrentIrql(); // 呼叫 ExAllocatePoolWithTag的irql必須<= DISPATCH_LEVEL ASSERT(irql <= DISPATCH_LEVEL); if (irql == DISPATCH_LEVEL) { DbgPrint("A caller executing at DISPATCH_LEVEL must specify a NonPagedXxx value for 土地買賣PoolType "); return NULL; } if (Size == 0) { return NULL; } return ExAllocatePoolWithTag( PagedPool, // 在這裡限定使用PagedPool的memory static_cast (Size), 酒店工作 NULL); // 不指定Tag}比較麻煩的做法,但可選擇POOL_TYPE是否分頁和是否在分配的memory上加Taginline void* __cdecl operator new(size_t Size, POOL_TYPE PoolType, ULONG PoolTag = NULL) { KIRQL irql = KeGetCurrentIrql(); // 檢查傳進來的PoolType是否合法 ASSERT(PoolType >=0 && PoolType < MaxPoolType); ASSERT(irql <= DISPATCH_LEVEL); // 在 烤肉>= DISPATCH_LEVEL的時後,是不能發生page fault的 if (irql == DISPATCH_LEVEL) { ASSERT(PoolType == NonPagedPool); } if (Size == 0) { return NULL; } return ExAllocatePoolWithTag( PoolType, 辦公室出租 static_cast (Size), PoolTag); }刪除記憶體都呼叫ExFreePool就行了inline void __cdecl operator delete(void* Pointer) { ASSERT(Pointer != NULL); 情趣用品ExFreePool(Pointer);}---------------------------------------------------------------------------------------------------------------------------至於new[]和delete[]方法一模一樣,直接改函式名就行了。第一種的new使用方式和在User Mode時一樣,但第二種有點不同。執行範例// 先宣告一個簡單的Int 類別class CInt{ public: explicit CInt() : m_nValue(0) { KdPrint(("Constructor had been called...\n")); Print(); } explicit 房屋買賣CInt(int nValue) : m_nValue(nValue) { KdPrint(("Constructor had been called...\n")); Print(); } ~CInt() { KdPrint(("Destructor had been called, Value=%d\n", m_nValue)); } void Print() { KdPrint(("Value=%d\n", m_nValue)); 酒店經紀} void Set(int nValue) { m_nValue = nValue; Print(); } operator int() { return m_nValue; } private: int m_nValue;}; // 第一種 CInt* pObj = new CInt(1); DbgPrint("sizeof(pObj)=%d\n", sizeof(*pObj)); delete pObj; // 第二種 pObj = new(NonPagedPool, 小型辦公室'1gaT') CInt(2); DbgPrint("sizeof(pObj)=%d\n", sizeof(*pObj)); delete pObj; // 第三種 CInt ObjAry[5]; for (int i=0; i<5; i++){ ObjAry[i].Set(i+3); } DbgPrint("sizeof(ObjAry)=%d\n", sizeof(ObjAry));執行結果Constructor had been called...Value=1sizeof(pObj)=4 Destructor had been called, Value=1Constructor had been called...Value=2sizeof(pObj)=4Destructor had been called, Value=2Constructor had been 借貸called...Value=0Constructor had been called...Value=0Constructor had been called...Value=0Constructor had been called...Value=0Constructor had been called...Value=0Value=3Value=4Value=5Value=6Value=7sizeof(ObjAry)=20Destructor had been called, Value=7Destructor had been called, Value=6Destructor had been called, Value=5Destructor had been called, Value=4Destructor had been called, Value=3---------------------------------------------------------------------------------------------------------------------------使用上要注意二點1. 因為Driver的程式的生命週期和User Mode的不同,無法當做全域變數使用。2.要注意Stack Overflow的問題,因信用貸款為在Kernel Mode分配到的Stack很小,約只有10幾K到幾十K, 不像User Mode的預設就是1 MB,要小心使用區域變數的空間和避免呼叫到太多層的函式。
.msgcontent .wsharing ul li { text-indent: 0; }
分享
Facebook
Plurk
YAHOO!
.msgcontent .wsharing ul li { text-indent: 0; }
分享
Plurk
YAHOO!
全站熱搜
留言列表