本文不介绍新的ATL7
服务器类和属性.这不是一个完整的列表
,只是我目前找到的.
串转换宏
有一些限制
.它从栈
中分配内存
,可能会在大串时溢出栈
.函数退出
时,释放该串
,而不是在函数
内引入的域
内释放
.
它使用过时OLE2ANSI
定义.如果你查看MSDN
上对_alloca
(来转换)的注意,它说它在SEH
或C++EH
中使用时有限制
.
如,看一下ATL3
的串转换宏
:
USES_CONVERSION;
try
{
for(int i=0; i< 100000; ++i)
LPTSTR str = OLE2T(L"Some string string string string string........");
|||//栈溢出,栈上的内存增长...
//如果上述没有失败,则确保`catch(int)`
throw int(1); //
}
catch(int)
{
LPTSTR str = OLE2T(L"Some string string string string string........");
||//`_alloca`不能在`SEH`中使用,否则`EH`生成未处理异常,在`VS.NET`中,`C++`编译时按错误标记
}
ATL7
:
串转换宏/类
在上述方面有所改进
.它对小串
使用栈内存
,对大串
使用堆,因此当栈空间
不足时不会溢出栈
.串在结束域
时释放
,而不是在函数退出
时释放.
可在异常处理器
中用.可在循环
中使用(因为可由域
控制).
宏名更易读.形式与以前一样:SourceType2[C]DestinationType
.
从:
1,AANSI/WUnicode/Tgeneric
到[常数]A,ANSI/W,Unicode/T,generic
.
2,CA2T/CA2CT
,根据美标
定义从美标
到通用串_UNICODE
3,CT2A/CT2CA
,根据T定义从T通用串
到ANSI_UNICODE
串
4,CT2W/CT2CW
,从T通用串
到统一
串
5,CW2T/CW2CT
,根据_UNICODE
定义从统一
到通用串
6,CT2WEX/CT2CWEX
,可指定从T通用
到统一
串和缓冲
7,CW2TEX/CW2CTEX
,可指定从统一
到T的通用串和缓冲
8,CA2W
,从美标
到统一
9,CW2A
族,从统一
到美标
10,CW2AEX/CA2WEX
,上述某些typedef/macro
使用的实际类
.
所以上面代码像这样
,不会崩溃:
try
{
for(int i=0; i< 100000; ++i)
CW2A str(L"Some string string string string string........");
throw int(1);
}
catch(int)
{
CW2A str(L"Some string string string string string........");
}
注意警告.上述所有宏都不能在ATL3
代码构造
中使用:
LPTSTR str = CW2A(L"some string");
上面代码
是错误的.该行
后,会析构CW2AEX
创建的临时对象
.
注意,宏表示C++
类,并受域规则
控制.
要查看问题
,请试以下操作:
//使用以2初化串长`大小`,以确保栈大小不够,且对内存用`堆`
LPCTSTR szr = CW2AEX<2>(L"some string");
szr; //在这一行`szr`应该指向`垃圾`
CString
:另一个附加
是来操作串的CStringT
类.即使此类公开的方法与以前的MFCCString
相同.它不是旧的MFCCString
.
此类是模板的.它与char,wchar_t
和TCHAR
一起使用的又
很少.CString
是一个又
:
CStringT< TCHAR, StrTraitATL< TCHAR > > CAtlString;
根据是否使用MFC
重定义,这样:
//`#ifdef_AFX`
typedef CAtlString CString;
CStringT
自身在MFC/ATL
间共享.默认,它使用CRT
,但可定义_ATL_MIN_CRT
或_ATL_CSTRING_NO_CRT
来更改CRT
.
这反之又使编译器
可见相应的又
,如:
//使用`CRT`并有更多功能
CStringT< TCHAR, StrTraitATL< TCHAR, ChTraitsCRT< TCHAR > >
or
//不使用`CRT`,而是使用`win32API`串函数`(wvsprintf,lstrlen,CharNext`等)
CStringT< TCHAR, StrTraitATL< TCHAR >, ChTraitsOS<TCHAR> >
另一个CFixedStringT
类提供固定的预分配连续缓冲
,以优化管理内存
.
可通过实现IAtlStringMgr
,来自定义管理内存
,且已有CAtlStringMgr
实现.
它的构造器
带IAtlMemMgr
的指针,IAtlMemMgr
可以是预定义的实现
,也可是你自己的实现
:
1,CCRTHeap
,使用CRT
堆
2,CWin32Heap
,使用win32
堆
3,CComHeap
,使用COM
任务分配内存器
.
等.如:
CComHeap comHeap;
CAtlStringMgr mg(&comHeap);
CString str(&mg);
str += "some string";
用::CoTaskMemAlloc
来分配内存
.
"串和文本类"(MSDN)
"ATL/MFC
串转换宏"(MSDN)
ATL7
引入了新的集合类
.这些类的接口
与以前的MFC
集合类类似.
这些类是模板类
,可传递自己的CElementTraits
来处理特例
,如CopyElements,RelocateElements,CompareElements
和Hash
.
CAtlArray/CAtlList
://使用`CStringElementTraits`有效`查找`比较
CAtlArray<CString, CStringElementTraits<CString> > array;
//其他特征包括`CStringRefElementTraits,CStringElementTraitsI`
CAtlList<CString, CStringElementTraits<CString> > list;
list.AddHead(CString("hello"));
list.AddHead(CString("string"));
POSITION pos = list.Find("hello");
if(pos != NULL)
{
CString str = list.GetAt(pos);
}
CAtlMap
CAtlMap<CString, int, CStringElementTraits<CString> > map;
map.InitHashTable(269);
map["key1"] = 2;
map["key2"] = 2;
int value;
if(map.Lookup("key1", value));
红黑树实现
的CRBTree/CRBMap/CRBMultiMap
CRBMap<int, int> rbMap;
rbMap.SetAt(10, 20);
rbMap.SetAt(30, 40);
CRBMap<int, int>::CPair* p = rbMap.Lookup(30);
//`p->m_key;P->m_value;`
rbMap.RemoveKey(30);
其他各种更特化的类
:
CAutoPtrArray/CAutoPtrList/CComUnkArray/CHeapPtrList/CInterfaceArray/CInterfaceList
"集合类"(MSDN)
CWorkerThread<Win32ThreadTraits|CRTThreadTraits>:
简单示例
:
class WorkerClass : public IWorkerThreadClient
{
HANDLE m_hEvent;
CWorkerThread<Win32ThreadTraits> m_thread;
public:
WorkerClass()
{
m_thread.Initialize();
m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_thread.AddHandle(m_hEvent, this, NULL);
}
~WorkerClass()
{
m_thread.RemoveHandle(m_hEvent);
m_thread.Shutdown();
}
void ResumeThread()
{
::SetEvent(m_hEvent);
}
void FreezeThread()
{
::ResetEvent(m_hEvent);
}
private:
//`IWorkerThreadClient`
HRESULT Execute(DWORD_PTR dwParam, HANDLE hObject)
{
FreezeThread();
return S_OK;
}
HRESULT CloseHandle(HANDLE hHandle)
{
::CloseHandle(hHandle);
return S_OK;
}
};
Then:
{
WorkerClass work;
work.ResumeThread();
Sleep(5000);
work.ResumeThread();
Sleep(5000);
}
下面是CThreadPool
的理想用法:
struct IDoSomeWork
{
virtual void Work()=0;
};
class Work1 : public IDoSomeWork
{
void Work(){}
};
class Work2 : public IDoSomeWork
{
void Work(){}
};
class ThreadPoolWorker
{
public:
//支持`CThreadPoolWorker`原型
typedef IDoSomeWork* RequestType;
BOOL Initialize(void* pvWorkerParam)
{
return TRUE;
}
void Execute(RequestType request, void* pvWorkerParam,OVERLAPPED* pOverlapped)
{
request->Work();
}
void Terminate(void* pvWorkerParam)
{
}
};
{
CThreadPool<ThreadPoolWorker> pool;
pool.Initialize();
//
IDoSomeWork* pWork1=new Work1();
pool.QueueRequest(pWork1);
//
IDoSomeWork* pWork2=new Work2();
pool.QueueRequest(pWork2);
//
Sleep(5000);
delete pWork1; delete pWork2;
}
CHeapPtr<CComAllocator | CCRTAllocator>:
CHeapPtr<int, CComAllocator> ptr;
ptr.Allocate(100);
//该类不适合对象数组,因为它不调用`delete[]`,而只调用`删`.
CAutoPtr<CString> ptr(new CString("string"));
CAutoVectorPtr<CString> pVec(new CString[100]); //这会调用`delete[]`
CComGITPtr
中:管理GIT
表中的指针.创建GIT
并调用IGlobalInterfaceTable
方法.
其他更特化的类
包括:
1,CAutoPtrArray
2,CAutoPtrList
3,CComHeap
4,CComHeapPtr
5,CComPtrBase
6,CCRTAllocator
7,CCRTHeap
8,CGlobalHeap
9,CHandle
10,CHeapPtrBase
11,CHeapPtrList
12,CLocalHeap
13,CWin32Heap
管理内存类(MSDN)
1,CAtlFile
是win32API
的文件精简包装器
.CreateFile,ReadFile,WriteFile
等.
2,CAtlTemporaryFile
可用于临时文件
.会自动命名,打开,关闭和删除
它们.
3,CAtlFileMappingBase/CAtlFileMapping
可用来映射文件
:
CAtlTemporaryFile file;
CAtlFileMapping<char> filemap;
file.Create(NULL, GENERIC_READ|GENERIC_WRITE);
file.SetSize(1024);
filemap.MapFile(file, 1024, 0, PAGE_READWRITE, FILE_MAP_READ|FILE_MAP_WRITE);
char* pMem = filemap;
strcpy(pMem, "hello");
ATL7
包括win32API
安全性的包装器
.
快速示例:
CSid sidDenied;
sidDenied.LoadAccount("Leo");
CDacl dacl;
//试`拒绝`或`允许`并查看`OpenEvent`稍后的行为
dacl.AddDeniedAce(sidDenied, GENERIC_ALL);
//dacl.AddAllowedAce(sidDenied,GENERIC_ALL);
CSecurityDesc desc;
desc.SetDacl(dacl);
CSecurityAttributes secattr(desc);
//限制`命名事件的权限`
CHandle hEvent(CreateEvent(&secattr, FALSE, FALSE, "NamedEvent"));
//试用所有访问权限打开它
CHandle hEventOpen(OpenEvent(EVENT_ALL_ACCESS, FALSE, "NamedEvent"));
//如果在上面添加了`拒绝`,它应该会失败.如果添加了`允许`,则应会成功
if(GetLastError() == ERROR_ACCESS_DENIED)
ATLTRACE("\n\nAccess denied when opening event\n\n");
CSecurityDesc descCheck;
AtlGetSecurityDescriptor("NamedEvent",SE_KERNEL_OBJECT, &descCheck);
CDacl daclCheck;
descCheck.GetDacl(&daclCheck);
CSid::CSidArray sidarr;
daclCheck.GetAclEntries(&sidarr);
for(UINT i=0; i<sidarr.GetCount(); ++i)
{
ATLTRACE("%s\n", (LPCTSTR)sidarr[i].Sid());
ATLTRACE("%s\n", (LPCTSTR)sidarr[i].AccountName());
ATLTRACE("%s\n", (LPCTSTR)sidarr[i].Domain());
}
#import
现在可取progid/libid
而不仅是硬编码
的文件名
.如:
#import <libid:20000000C-500A-100BB005-000000000000> version("2.2")
#import "progid:SomeServer.哈哈.1" embedded_idl, no_namespace
1,按如:CAtlComModule/CAtlWinModule/CAtlDllModuleT/CAtlExeModuleT/CAtlServiceModuleT/等
其他类替换CComModule
.
2,不再显式调用Init()/Term()
.这些方法现在由模块类
的相应ctor/dtor
调用.
3,不再需要BEGIN_OBJECT_MAP/END_OBJECT_MAP
.改用全局域内的OBJECT_ENTRY_AUTO
.
4,并在链接
时自动生成
到ATL
对象映射中.它使用链接器段
声明把所有全局的映射项
收集到一个列表
中.
CComCurrency
,CURRENCY
类型的包装器
CAtlException
,定义与ATL
相关的异常
CImage
,根据GDI+
.可用jpeg,gif,bmp,png
.见"早期系统的CImage
限制"(MSDN)
_U_STRINGorID/_U_MENUorID/_U_RECT/CPoint/CRect/CSize
,各种简单的包装器.见"工具类"(MSDN)
atlsync.h
中定义的同步包装器
:CCriticalSection,CEvent,CMutex
和CSemaphore
.但在MSDN
中没有记录它们
.