以下代码:
#include <iostream>
#include <Windows.h>
using namespace std;
int main ()
{ LPWSTR buffer; //or wchar_t * buffer;
GetModuleFileName(NULL, buffer, MAX_PATH) ;
cout<<buffer;
cin.get();
cin.get();
}
应该显示程序执行的完整路径。但是在VS 2012中,我得到了错误:
使用了未初始化的局部变量“buffer”
代码有什么问题?
6条答案
按热度按时间cunj1qz11#
你需要给予它一个缓冲区,可以容纳一些字符;
例如。
vof42yt12#
VS正确地指出你正在使用一个未初始化的缓冲区-
buffer
var是一个指向WSTR
的指针,但是它没有被静态缓冲区初始化,也没有被分配。另外,您应该记住MAX_PATH
通常是不够的,特别是在具有长路径名的现代系统上。既然你正在使用C++,那么使用它的特性将是一个很好的实践。我可以假设以下代码:
std::string
和std::wstring
的标准不保证具有连续的数据,并且可能不安全地用作缓冲区。但是,它们在所有主要标准库中都是连续的。vktxenjb3#
这是Win32 API的一个普遍问题,函数将字符串返回到一个有限大小的缓冲区,你永远不知道你的缓冲区是否足够大来容纳整个字符串。正如kingsb提到的,即使MAX_PATH现在也不是一个足够好的路径常量。
我倾向于使用一个通用的helper函数来实现这个目的:
对于GetModuleFileName,可以这样使用:
对于LoadString,像这样:
zengzsys4#
而且,在我下面的答案的旁注/补充:有时候,你想访问一个函数
size_t GetString(char* buf = NULL, size_t bufsize = 0);
,如果你不带任何参数调用它,它将返回必要的缓冲区大小,如果你正常调用它,最多写入bufsize字符到buf(或者直到它想要返回的字符串的末尾,无论先到的),返回实际写入的字符数。一个实现可能看起来像这样:这通常发生在类工厂中,这些工厂位于DLL中,并且由于内存管理的原因,不想交换复杂类型,如std::string。要使用接口,您通常会以丑陋的代码结束:
这很糟糕,原因很明显,一个是你不能直接在流插入中使用它。经过一些拖延和撕扯我的头发,我想出了几乎色情的解决方案,至少在模板和成员函数指针的使用方面:
其然后可以以以下方式使用:
仍然有点复杂,但大部分繁重的工作都隐藏在幕后。
5m1hhzi45#
我还遇到了信任
char pszPath[_MAX_PATH]
足以让::GetModuleFilename()
正常工作的问题(事实并非如此!)。因此,我冒昧地对Ivan的建议进行了一点修改,得出了以下代码你可以用多种方式来使用,e。例如:
如果你对lambda表达式没问题的话。如果成员变量是必需的,因为在DLL中经常会将HMODULE存储在
DllMain(HMODULE hm, DWORD ul_reason_for_call, LPVOID)
中,则必须添加this指针,如下所示:当然,“老式的方式”也可以像这个测试用例中所示的那样工作:
你甚至可以使用TCHAR进行ANSI/UNICODE抽象,类似于这样:
或者
#include <tstdlib.h>
,我不知道从哪里弄来的:3j86kqsm6#
你可以试试这个: