LPCTSTR LPCWSTR LPCSTR 含义

#ifdef UNICODE
#define LPCTSTR LPCWSTR
#else
#define LPCTSTR LPCSTR
#endif

LPCTSTR A 32-bit pointer to a constant character string that is portable for Unicode and DBCS. An LPCWSTR if UNICODE is defined, an LPCSTR otherwise.

LPCWSTR Pointer to a constant null-terminated string of 16-bit Unicode characters. For more information,

LPCSTR Pointer to a constant null-terminated string of 8-bit Windows (ANSI) characters. For more information

LP:指针
C:const
W:wide宽字符

 LPCTSTR类型

  如何理解LPCTSTR类型?

  L表示long指针 这是为了兼容Windows 3.1等16位操作系统遗留下来的,在win32中以及其他的32为操作系统中, long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。

  P表示这是一个指针

  C表示是一个常量

  T表示在Win32环境中, 有一个_T宏

  这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。

  STR表示这个变量是一个字符串

  所以LPCTSTR就表示一个指向常固定地址的可以根据一些宏定义改变语义的字符串。

  同样, LPCSTR就只能是一个ANSI字符串,在程序中我们大部分时间要使用带T的类型定义。

  LPCTSTR == const TCHAR *

  CString 和 LPCTSTR 可以说通用。 原因在于CString定义的自动类型转换,没什么奇特的,最简单的C++操作符重载而已。

  常量字符串ansi和unicode的区分是由宏_T来决定的。但是用_T("abcd")时, 字符串"abcd"就会根据编译时的是否定一_UNICODE来决定是char* 还是 w_char*。 同样,TCHAR 也是相同目的字符宏。 看看定义就明白了。简单起见,下面只介绍 ansi 的情况,unicode 可以类推。

  ansi情况下,LPCTSTR 就是 const char*, 是常量字符串(不能修改的)。

  而LPTSTR 就是 char*, 即普通字符串(非常量,可修改的)。

  这两种都是基本类型, 而CString 是 C++类, 兼容这两种基本类型是最起码的任务了。

  由于const char* 最简单(常量,不涉及内存变更,操作迅速), CString 直接定义了一个类型转换函数

  operator LPCTSTR() {......}, 直接返回他所维护的字符串。

  当你需要一个const char* 而传入了CString时, C++编译器自动调用 CString重载的操作符 LPCTSTR()来进行隐式的类型转换。

  当需要CString , 而传入了 const char* 时(其实 char* 也可以),C++编译器则自动调用CString的构造函数来构造临时的 CString对象。

  因此CString 和 LPCTSTR 基本可以通用。

  但是 LPTSTR又不同了,他是 char*, 意味着你随时可能修改里面的数据,这就需要内存管理了(如字符串变长,原来的存贮空间就不够了,则需要重新调整分配内存)。

  所以 不能随便的将 const char* 强制转换成 char* 使用。

  楼主举的例子

  LPSTR lpstr = (LPSTR)(LPCTSTR)string;

  就是这种不安全的使用方法。

  这个地方使用的是强制类型转换,你都强制转换了,C++编译器当然不会拒绝你,但同时他也认为你确实知道自己要做的是什么。因此是不会给出警告的。

  强制的任意类型转换是C(++)的一项强大之处,但也是一大弊端。这一问题在 vc6 以后的版本(仅针对vc而言)中得到逐步的改进(你需要更明确的类型转换声明)。

  其实在很多地方都可以看到类似

  LPSTR lpstr = (LPSTR)(LPCTSTR)string;

  地用法,这种情况一般是函数的约束定义不够完善的原因, 比如一个函数接受一个字符串参数的输入,里面对该字符串又没有任何的修改,那么该参数就应该定义成 const char*, 但是很多初学者弄不清const地用法,或者是懒, 总之就是随意写成了 char* 。 这样子传入CString时就需要强制的转换一下。

  这种做法是不安全的,也是不被建议的用法,你必须完全明白、确认该字符串没有被修改。

  CString 转换到 LPTSTR (char*), 预定的做法是调用CString的GetBuffer函数,使用完毕之后一般都要再调用ReleaseBuffer函数来确认修改 (某些情况下也有不调用ReleaseBuffer的,同样你需要非常明确为什么这么做时才能这样子处理,一般应用环境可以不考虑这种情况)。

  同时需要注意的是, 在GetBuffer 和 ReleaseBuffer之间,CString分配了内存交由你来处理,因此不能再调用其他的CString函数。

  CString 转LPCTSTR:

  CString cStr;

  const char *lpctStr=(LPCTSTR)cStr;

  LPCTSTR转CString:

  LPCTSTR lpctStr;

  CString cStr=lpctStr;

相互转换方法:

LPWSTR->LPTSTR:   W2T();
LPTSTR->LPWSTR:   T2W();
LPCWSTR->LPCSTR: W2CT();
LPCSTR->LPCWSTR: T2CW();

ANSI->UNICODE:    A2W();

UNICODE->ANSI:     W2A();

时间: 2025-01-05 02:03:03

LPCTSTR LPCWSTR LPCSTR 含义的相关文章

LPTSTR、LPCSTR、LPCTSTR、LPSTR的来源及意义

UNICODE:它是用两个字节表示一个字符的方法.比如字符'A'在ASCII下面是一个字符,可'A'在UNICODE下面是两个字符,高字符用0填充,而且汉字'程'在ASCII下面是两个字节,而在UNICODE下仍旧是两个字节.UNICODE的用处就是定长表示世界文字,据统计,用两个字节可以编码现存的所有文字而没有二义. MBCS,它是多字节字符集,它是不定长表示世界文字的编码.MBCS表示英文字母时就和ASCII一样(这也是我们容易把MBCS和ASCII搞混的原因),但表示其他文字时就需要用多字

vc字符串转换处理:(绝对精华,收集所有的例子)

vc字符串转换处理:(绝对精华,收集所有的例子) 1.头文件中要定义宏; #define   UNICODE         #define   _UNICODE     //////////////////// char   buf[128];    memset(buf,0,128);     strcpy(buf,"你好");     WCHAR   pCName[128];     memset(pCName,0,128);     MultiByteToWideChar(CP

加载dll、lib库

2.是关于如何加载dll或lib库的.可以看这篇bog   Qt调用dll中的功能函数点击打开链接 **************************************************************************************************************************************************** 声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有

程序破解之 API HOOK技术 z

API HOOK,就是截获API调用的技术,在程序对一个API调用之前先执行你的函数,然后根据你的需要可以执行缺省的API调用或者进行其他处理,假设如果想截获一个进程对网络的访问,一般是几个socket API : recv,recvfrom, send, sendto等等,当然你可以用网络抓包工具,这里只介绍通过API HOOK的方式来实现, 主要原理是在程序运行中动态修改目标函数地址的内存数据,使用jmp语句跳转到你的函数地址,执行完后再恢复内存数据, 汇编代码是: mov eax, pNe

MFC中的几种播放声音的方法

一.播放声音文件的简单方法 在VC++ 中的多媒体动态连接库中提供了一组与音频设备有关的函数.利用这些函数可以方便地播放声音.最简单的播放声音方法就是直接调用VC++中提供的声音播放函 数BOOL sndPlaySound ( LPCSTR lpszSound,UINT fuSound ); 或BOOL PlaySound( LPCSTR lpszSound, HMODULE hmod, DWORD fuSound );其中参数lpszSound是需要播放声音的.WAV文件的路径和文件名, hm

ATL字符串转换宏

在头文件<atlconv.h>中定义了ATL提供的所有转换宏,如:   A2CW       (LPCSTR)  -> (LPCWSTR)   A2W        (LPCSTR)  -> (LPWSTR)   W2CA       (LPCWSTR) -> (LPCSTR)   W2A        (LPCWSTR) -> (LPSTR) 所有的宏如下表所示: A2BSTR OLE2A T2A W2A A2COLE OLE2BSTR T2BSTR W2BSTR A

【转】QT QString, wchar_t *, TCHAR, CString和其他字符或字符串类型的转化

//QString to wchar_t *: const wchar_t * encodedName = reinterpret_cast<const wchar_t *>(fileName.utf16()); //QString to char * given a file name: QByteArray fileName = QFile::encodeName(aFileName); const char * encodedName = fileName.constData(); //

USES_CONVERSION宏(转)

date:2018.10.23 USES_CONVERSION是ATL中的一个宏定义.用于编码转换(用的比较多的是CString向LPCWSTR转换).在ATL下使用要包含头文件#include "atlconv.h" 使用USES_CONVERSION一定要小心,它们从堆栈上分配内存,直到调用它的函数返回,该内存不会被释放.如果在一个循环中,这个宏被反复调用几万次,将不可避免的产生stackoverflow. 在一个函数的循环体中使用A2W等字符转换宏可能引起栈溢出. #includ

Windows 平台编程的字符串那些注意的东西

Unicode 与多字节 Windows 支持 Unicode 后, 所有和字符串相关的 Windows API 都有了两个版本, 以 _A 结尾的和带 _W 结尾. 比如函数 MessageBox 就有 MessageBoxA 和 MessageBoxW 两个版本. MessageBox 只是一个宏,在编译的时候根据项目的字符集设置, 用 MessageBoxA 或者 MessageBoxW 替换. User32.dll 导出了 MessageBoxA 和 MessageBoxW, 没有导出