- LPCWSTR
LPCWSTR 是Unicode字符串指针,typedef __nullterminated CONST WCHAR *LPCWSTR, *PCWSTR; in WinNT.h
Convert example:
LPCWSTR text;
LPWSTR l=const_cast<LPWSTR>(text);
unsigned int maxResultSize=100;
const std::wstring ws=something;
LPWSTR lp;
wcsncpy_s(lp, maxResultSize, ws.c_str(), ws.size();
在头文件<atlconv.h>中定义了ATL提供的所有转换宏,如:
A2CW (LPCSTR) -> (LPCWSTR)
A2W (LPCSTR) -> (LPWSTR)
W2CA (LPCWSTR) -> (LPCSTR)
W2A (LPCWSTR) -> (LPSTR)
所有的宏如下表所示:
A2BSTR |
OLE2A |
T2A |
W2A |
A2COLE |
OLE2BSTR |
T2BSTR |
W2BSTR |
A2CT |
OLE2CA |
T2CA |
W2CA |
A2CW |
OLE2CT |
T2COLE |
W2COLE |
A2OLE |
OLE2CW |
T2CW |
W2CT |
A2T |
OLE2T |
T2OLE |
W2OLE |
A2W |
OLE2W |
T2W |
W2T |
上表中的宏函数,非常的有规律,每个字母都有确切的含义如下:
2 |
to 的发音和 2 一样,所以借用来表示“转换为、转换到”的含义。 |
A |
ANSI 字符串,也就是 MBCS。 |
W、OLE |
宽字符串,也就是 UNICODE。 |
T |
中间类型T。如果定义了 _UNICODE,则T表示W;如果定义了 _MBCS,则T表示A |
C |
const 的缩写 |
利用这些宏,可以快速的进行各种字符间的转换。使用前必须包含头文件,并且申明USER_CONVERSION;使用 ATL 转换宏,由于不用释放临时空间,所以使用起来非常方便。但是考虑到栈空间的尺寸(VC 默认2M),使用时要注意几点:
1、只适合于进行短字符串的转换;
2、不要试图在一个次数比较多的循环体内进行转换;
3、不要试图对字符型文件内容进行转换,因为文件尺寸一般情况下是比较大的;
4、对情况 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();
Pasted from <http://www.cnblogs.com/foolboy/archive/2005/07/25/199869.html>
2.HRESULT
HRESULT 是一种简单的数据类型,通常被属性和 ATL 用作返回值。下表说明各种不同的值。头文件 winerror.h 中包含更多的值。
HRESULT 其实是一个双字节的值,其最高位(bit)如果是0表示成功,1表示错误。
HRESULT hr = 调用组件函数;
if( SUCCEEDED( hr ) ){...} // 如果成功
......
if( FAILED( hr ) ){...} // 如果失败
......
Pasted from <http://baike.baidu.com/view/1754469.htm>
3.什么是BSTR
BSTR是“Basic STRing”的简称,微软在COM/OLE中定义的标准字符串数据类型。
对于C++,Windows头文件wtypes.h中定义如下:
typedef wchar_t WCHAR;
typedef WCHAR OLECHAR;
typedef OLECHAR __RPC_FAR *BSTR;;
字符串相关类型的推荐选择顺序
优先级 |
类型 |
说明 |
最高 |
stl::string/wstring |
●功能最完善,可移植性最好。 |
|
CString |
●如果编码规范限制使用STL的时候,推荐CString。 ●VC 6的版本很不完善。.Net有明显改进,需要进一步研究 |
|
C/C++ basic type (TCHAR* / char* / LPTSTR / LPCTSTR / TCHAR[]) |
●在结构体中,优先使用指定最大长度的字符数组。 ●效率最好 |
|
CComBSTR/ _bstr_t |
●在必须使用BSTR时的优先选择。 ●在ATL(COM component)工程或者工程中必须使用ATL中,优先选择CComBSTR。一般Exe/dll如果_bstr_t能满足要求,优先使用_bstr_t。 ●对于VC6,使用_bstr_t一定要慎重,最好只用作简单临时变量保存调被调用函数的传入参数。因为_bstrt_t不能支持一些关键性操作,比如Detach。 ● 对于VC++ .Net推荐使用_bstr_t,它是C++扩展,不需要额外包含ATL的文件。 |
最低 |
BSTR |
● COM接口 |
Pasted from <http://baike.baidu.com/view/3346619.htm>
4.CComBSTR
1. char
基本类型,1 byte 的串
2. wchar_t
unicode 串 2 byte
3. TCHAR
在16位程序下,表示为char,单字节
在32位程序下,表示为unicode,两字节
4. 根据上面产生许多变种,一般都有相应的大定形式; 当在其中有P时,表示指针; 当在其中有C时,表示是常量
5. BSTR
定义的数据类型,一般COM调用的参数串
当define _UNICODE 它表示unicode串
否则 它表示ansi串
对了, 它前面有一个长度
6. CString _bstr_t CComBSTR 这三个是最好的东东
CString 封装了char 与 w_char_t
_bstr_t 封装了BSTR
CComBSTR 封装了BSTR
CComBSTR、_bstr_t、BSTR、LPCTSTR、LPSTR、char *、CString
CComBSTR 是专门为COM的通用性而定制的一种格式
BSTR : unsigned short* 32位字符指针
LPCTSTR const char* 指向字符串常量的32位指针
char *; 字符串指针。
CString 字符串类。
LPTSTR const char* 指向可移植到Unicode和DBCS字符串常量的32位指针
LPSTR char * 可移植为的Unicode和DBCS字符串的32位指针。
Pasted from <http://topic.csdn.net/t/20020427/15/681769.html>
4.std::wstring
Convert example:
const std::wstring obj;
const wchar_t *wt= obj.c_str();
Code : std::wstring ws;
ws=ws + L"" + BSTR
第0种方法:
std::wstring s2ws(const std::string& s)
{
std::wstring temp(s.length(),L‘ ‘);
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}
std::string ws2s(const std::wstring& s)
{
std::string temp(s.length(), ‘ ‘);
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}
第一种方法:调用WideCharToMultiByte()和MultiByteToWideChar(),
#include <string>
#include <windows.h>
using namespace std;
//Converting a WChar string to a Ansi string
std::string WChar2Ansi(LPCWSTR pwszSrc)
{
int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
if (nLen<= 0) return std::string("");
char* pszDst = new char[nLen];
if (NULL == pszDst) return std::string("");
WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
pszDst[nLen -1] = 0;
std::string strTemp(pszDst);
delete [] pszDst;
return strTemp;
}
string ws2s(wstring& inputws){ return WChar2Ansi(inputws.c_str()); }
//Converting a Ansi string to WChar string
std::wstring Ansi2WChar(LPCSTR pszSrc, int nLen)
{
int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
if(nSize <= 0) return NULL;
WCHAR *pwszDst = new WCHAR[nSize+1];
if( NULL == pwszDst) return NULL;
MultiByteToWideChar(CP_ACP, 0,(LPCSTR)pszSrc, nLen, pwszDst, nSize);
pwszDst[nSize] = 0;
if( pwszDst[0] == 0xFEFF) // skip Oxfeff
for(int i = 0; i < nSize; i ++)
pwszDst[i] = pwszDst[i+1];
wstring wcharString(pwszDst);
delete pwszDst;
return wcharString;
}
std::wstring s2ws(const string& s){ return Ansi2WChar(s.c_str(),s.size());}
第二种方法:采用ATL封装_bstr_t的过渡:(注,_bstr_是Microsoft Specific的,所以下面代码可以在VS2005通过,无移植性);
#include <string>
#include <comutil.h>
using namespace std;
#pragma comment(lib, "comsuppw.lib")
string ws2s(const wstring& ws);
wstring s2ws(const string& s);
string ws2s(const wstring& ws)
{
_bstr_t t = ws.c_str();
char* pchar = (char*)t;
string result = pchar;
return result;
}
wstring s2ws(const string& s)
{
_bstr_t t = s.c_str();
wchar_t* pwchar = (wchar_t*)t;
wstring result = pwchar;
return result;
}
Pasted from <http://keyknight.blog.163.com/blog/static/36637840200931992556387/>
5.std::pair
#include <iostream>
02 |
#include <utility> |
03 |
#include <string> |
04 |
using namespace std; |
05
06 |
int main () { |
07 |
pair <string,double> product1 ("tomatoes",3.25); |
08 |
pair <string,double> product2; |
09 |
pair <string,double> product3; |
10
11 |
product2.first = "lightbulbs"; // type of first is string |
12 |
product2.second = 0.99; // type of second is double |
13
14 |
product3 = make_pair ("shoes",20.0); |
15
16 |
cout << "The price of " << product1.first << " is $" << product1.second << "/n"; |
17 |
cout << "The price of " << product2.first << " is $" << product2.second << "/n"; |
18 |
cout << "The price of " << product3.first << " is $" << product3.second << "/n"; |
19 |
return 0; |
20 |
} |
Pasted from <http://www.cnblogs.com/lilun/archive/2010/11/01/1865946.html>
6.std::vector
简单来讲,std::vector 是一个动态数组,管理的是一块线性的、可动态增长的内存。
如何加速 std::vector?
使用 vector::reserve
在大致可预估 vector 大小时,在插入数据前,应该先调用 reserve(size) 进行内存的预分配(这里 size是预估的vector元素个数)。
避免在vector开始(begin)插入/删除数据
也就是说,应该尽量用 vector::insert(end(), …) 或者 vector::push_back/pop_back添加/删除数据。而不要用 vector::insert(begin(), …)操作。vector 没有提供 push_front操作,原因只有一个:从 vector 开始处插入/删除数据是低效的做法。
如果你需要大量的在容器开始(begin)处 insert 数据,那么可以选择 std::deque(有 vector随机访问的优点,也有 list 高效插入的优点)或者 std::list.
std::vector 的缺陷
什么时候不能用 std::vector ?
在容器需要容纳海量数据,并且元素个数不可预知时,坚决不能用 std::vector.所有基于线性内存的数据结构(如std::vector,std::string)在海量数据时,遭遇性能瓶颈。
内存碎片
基于线性内存的数据结构(如 std::vector,std::string),还有一个典型的问题,就是容易产生内存碎片。在大量操作std::vector 或 std::string 后,内存碎片就会比较严重。
std::vector 与 allocator
我们知道,std::vector 的原型是:
template >
class vector;
那么是否需要像我们针对Map/MultiMap、Set/MultiSet、List/Slist、HashMap/HashMultiMap、HashSet/HashMultiSet、Deque 做的那样,将 AllocT 改用 GC Allocator呢?
答案是:不需要。GC Allocator 对于改善小内存分配是有益的。但是在动态的线性内存的数据结构无效。这样的数据结构除了std::vector 外,典型的还有 std::string(std::basic_string)。
Pasted from <http://blog.sina.com.cn/s/blog_523491650100it94.html>
7._bstr_t
bstr_t类封装BSTR有趣的地方就是它的封装方式有点类似于智能指针,又有点像COM管理生存期的方式。_bstr_t将两者结合起来并具体体现在构造函数、赋值函数和析构函数中。
_variant_t和_bstr_t这两个类分别封装并管理VARIANT和BSTR这两种数据类型,
VARIANT和BSTR这两种类型是COM中使用的数据类型。
为了C++中的变量应用到ADO编程中,只能进行数据类型的转换。
通过_variant_t和_bstr_t这两个类,就可以方便的把C++类型变量转换成COM中的变量了
ADO是基于COM接口x实现的因此ta它的使用对于正在进行的 COMCOM编程的程序员而言更简单
COMshi使用其特定的数据类型,_bstr_t是其中一种源类型
其他类型转换成_bstr_t可以直接赋值。
例子:
_bstr_t bstr("程序员");
const char *buf=bstrVar;
Convert example:
_bstr_t t("123");
t.GetBSTR();
_variant_t((LONG)value);
_variant_t v(something);
v.vt==VT_EMPTY || v.vt==VT_BSTR || v.vt==VT_NULL
Pasted from <http://baike.baidu.com/view/3885275.htm>
8.boost::function
1. 介绍
Boost.Function 库包含了一个类族的函数对象的包装。它的概念很像广义上的回调函数。其有着和函数指针相同的特性但是又包含了一个调用的接口。一个函数指针能够在能以地方被调用或者作为一个回调函数。boost.function能够代替函数指针并提供更大的灵活性。
2. 使用
Boost.Function 有两种形式:首选形式和便携式形式, 其语法如下:
首选形式 |
便携式形式 |
boost::function<float(int x, int y)>f |
boost::function2<float, int, int>f |
但是便携式形式不是所有的编译器都支持的, 所以这里我只介绍首选形式。
2.1 普通函数
我们可以看下如下的例子:
1 void do_sum(int *values, int n)
2 {
3 int sum(0);
4 for (int i = 0; i < n; ++i)
5 {
6 sum += values[i];
7 }
8 cout << sum << endl;
9 };
10 int _tmain(int argc, _TCHAR* argv[])
11 {
12 boost::function<void(int *values, int n)> sum;
13 sum = &do_sum;
14 int a[] = {1,2,3,4,5};
15 sum(a, 5);
16 return 0;
17 }
sum 可以理解为一个广义的函数对象了,其只用就是保存函数do_sum, 然后再调用之。
2.2 成员函数
在很多系统中, 对于类的成员函数的回调需要做特殊处理的。这个特殊的处理就是“参数绑定”。当然这个超出了我们讨论的范围了。 boost::function对于成员函数的使用可以看下如下代码:
1 class X{
2 public:
3 int foo(int a)
4 {
5 cout << a <<endl;
6 return a;
7 }
8 };
9 int _tmain(int argc, _TCHAR* argv[])
10 {
11 boost::function<int(X*, int)>f;
12 f = &X::foo;
13 X x;
14 f(&x, 5);
15 return 0;
16 }
我们发现, 对类的成员函数的对象化从语法是没有多大的区别。
3. 一个典型的例子
上面的几个例子没有体现出boost::function的作用来, 这里在写一个例子。比如当程序执行到某一处的时候想绑定某一个函数, 但是不想立即执行, 我们就可以声明一个函数对象,给此对象绑定相应的函数, 做一些其他事情,然后再来执行绑定的函数, 代码如下:
1 void print(int a)
2 {
3 cout << a << endl;
4 }
5 typedef boost::function<void (int)> SuccessPrint;
6 int _tmain(int argc, _TCHAR* argv[])
7 {
8 vector<SuccessPrint> printList;
9 SuccessPrint printOne = boost::bind(print, _1);
10 printList.push_back(printOne);
11 SuccessPrint printTwo = boost::bind(print, _1);
12 printList.push_back(printTwo);
13 SuccessPrint printThree = boost::bind(print, _1);
14 printList.push_back(printTwo);
15 // do something else
16 for (int i = 0; i < printList.size(); ++i)
17 printList.at(i)(i);
18 return 0;
19 }
上述代码中首先把声明一个函数对象 typedef boost::function<void (int)> SuccessPrint, 然后把print绑定到斥对象中, 放入vector中, 到最后才来执行这print()函数。
Pasted from <http://www.cnblogs.com/sld666666/archive/2010/12/16/1907591.html>
Others:
boost::lexical_cast
boost::lexical_cast<std::wstring>(
boost::posix_time
boost::shared_ptr<DatabaseUtils>
boost::shared_ptr<PolicyPath::PoliciesVector>
boost::wformat
boost::bind(
boost::mem_fn(
boost::optional<>
boost::function<delegate * ...>