2010-11-09 185 views
0

我正在整理一些很久以前写过的代码,并将其放入方法之类,当我尝试从输入提示符中获取输入字符串和LPCWSTR以进行目录搜索时。通过引用传递LPCWSTR

void GetInfo(string &stdStr, LPCWSTR &wStr) 
{ 
    cout << endl << "Enter String: "; 
    getline(cin, stdStr); 

    string sTempP = stdStr; 

    #ifdef UNICODE 
     std::wstring wTemp = s2ws(stdStr); 
     wStr = wTemp.c_str(); 
    #else 
     wStr = stdStr.c_str(); 
    #endif 

    stdStr = sTempP; 

    return; 
} 

当我打电话

string directoryName; 
LPCWSTR directory_Name; 
GetInfo(directoryName, directory_Name); 

性病串工作正常,但LPCWSTR给我的垃圾。他们都在这个方法中工作得很好,所以我想知道如何通过引用传递这个字符串奇怪地工作?

哦,我试着写一个函数,将一个std :: string转换为LPCWSTR并将该变量赋值给那个,但那也很奇怪。如果在主体中定义的代码工作正常,它只是当我遇到问题的函数内。

感谢,

弗雷泽

回答

3

在代码中有几件事情我会改进,但你的主要问题是LPCWSTR指针到一个字符串,而不是一个字符串。您正在为wStr分配一个新的指针值,但在函数返回时,指向的内存不再有效。

定义UNICODE时,一旦wTemp不在范围内,该存储器将不再有效。在没有定义UNICODE的情况下,指针不再有效,因为它指向当您调用c_str()时包含在stdStr中的数据。执行时

stdStr = sTempP; 

以前返回给您的指针不能再被视为有效。

LPCWSTR只是一个Windows typedefconst wchar_t *。你会更好改变GetInfo的签名是这样的:

void GetInfo(string &stdStr, wstring &wStr); 

并相应地更改代码。假设你需要得到一个LPCWSTR调用Win32 API函数类的东西,这里是你如何能做到这一点:

string directoryName; 
wstring directory_Name; 
GetInfo(directoryName, directory_Name); 
LPCWSTR p_directory_Name = directory_Name.c_str(); 
+0

非常好!非常丰富,谢谢。 Win32 API编程不是我已经有很多经验,你可以告诉... – 2010-11-09 23:21:47

0

LPCWSTR仅仅是const wchar_t*一个typedef。

您可以使用std::wstringstd::wstring::c_str()检索LPCWSTR

此外,如果您愿意,可以使用boost::lexical_cast的专门外观将std::string转换为std::wstring,这是非常简单的方法。

0

stdStr.c_str()的结果在stdStr = sTempP之后变为无效。

0

LPCWSTR只是一个指针(在Windows头文件中定义),而std::string是一个完整的C++类。

因此,该行刚刚修改输入指针值 - 你将需要由字节(std::copy或类似)的值字节与stdStr.c_str()复制到LPCWSTR编址的内存这个工作(假设有足够的空间,以及正确的空终止)。

wStr = stdStr.c_str(); 

这也是危险的,因为当字符串超出范围的c_str()返回的值是不是不再有效,让你的LPCSWTR指向内存访问时,将导致不确定的行为。

正如你所看到的,如果你只打算使用已经存在的内存,通过引用传递原始指针没有太多意义。如果您计划将输入指针替换为在返回时保持有效的新内存区域的地址(伴随着所有权头痛,所以仍然不是一个好主意),这只会很有用。

0

c_str()方法返回的是由你叫他们在对象管理的指针。 sTempPwTemp对象是GetInfo函数的本地对象,因此在该函数返回时,这两个对象都已被销毁,并且以前由c_str()返回的指针不好。

看起来像LPCWSTR是专为C编程,而不是C++。因此,您必须找到可以使用的对象类型而不是LPCWSTR,或者通过分配空间和复制数据并再次释放来执行一些额外的管理。