LoadString 是否为其写入的字符串分配内存?
Does LoadString allocate memory for the string it writes to?
我是 c++ 的新手,需要一些帮助。
我创建了一个包含字符串的纯资源 dll,我需要在不同的项目中使用这个 dll 来读取存储的字符串。
我编写了以下函数来读取字符串:
LPTSTR GetResourceStr(HMODULE resContainer,int resourceID)
{
//The stings that are stored in the dll are:
//
//ID |Value|Caption
//__________________________________________
//IDS_STRING101 |101 |stringggg
//IDS_STRING102 |102 |string 102
//IDS_STRING103 |103 |string 103
LPTSTR strBuffer = NULL;//is a (non-const) TCHAR string
if(0!=resContainer){
int copied=LoadString(resContainer,resourceID ,(LPTSTR)&strBuffer,0);
}
return strBuffer;
}
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE resContainer=LoadLibraryEx(L"ResourceDll.dll",NULL, LOAD_LIBRARY_AS_DATAFILE);
LPTSTR msg = GetResourceStr(resContainer,101);
std::wcout<<msg<<std::endl;
//Expected output: stringggg
//The output that i get: stringgggstring 102 string 103
int i = 0;
std::cin>>i;
return 0;
}
我应该在我的代码中更改什么以获得 预期输出 - stringggg?
为什么会这样?
LoadString 是否为其从资源中读取的字符串分配了内存,或者我只是得到了指向内存中字符串已存储位置的指针?
感谢您的帮助!!
nBufferMax [in]
Type: int
The size of the buffer, in characters. The string is truncated and null-terminated if it is longer than the number of characters specified. If this parameter is 0, then lpBuffer receives a read-only pointer to the resource itself.
所以直接回答你的问题,你只是得到一个指向存储资源的内存的指针。
但是字符串资源不是以 null 结尾的(有关详细信息,请参阅 here),所以这就是您获得该输出的原因。 LoadString 的 return 值告诉您单个字符串资源的长度。如果您需要字符串以 null 结尾,则必须将字符串复制到单独的缓冲区,如下所示:
WCHAR* pszString;
int iLength = ::LoadString(
resContainer,
resourceID,
reinterpret_cast<LPWSTR>(&pszString),
0
);
WCHAR* pszString2 = new WCHAR[iLength + 1];
::StringCchCopyN(pszString2, iLength + 1, pszString, iLength);
或者,您可以调用 LoadString,将指向缓冲区的指针(而不是指向指针的指针)作为第 3 个参数,并将缓冲区的长度作为第 4 个参数,这会将字符串资源复制到缓冲区并以 null 终止它。缺点是如果你传的长度不够大,字符串会被截断,而且没办法提前查询到资源的长度。
我是 c++ 的新手,需要一些帮助。 我创建了一个包含字符串的纯资源 dll,我需要在不同的项目中使用这个 dll 来读取存储的字符串。
我编写了以下函数来读取字符串:
LPTSTR GetResourceStr(HMODULE resContainer,int resourceID)
{
//The stings that are stored in the dll are:
//
//ID |Value|Caption
//__________________________________________
//IDS_STRING101 |101 |stringggg
//IDS_STRING102 |102 |string 102
//IDS_STRING103 |103 |string 103
LPTSTR strBuffer = NULL;//is a (non-const) TCHAR string
if(0!=resContainer){
int copied=LoadString(resContainer,resourceID ,(LPTSTR)&strBuffer,0);
}
return strBuffer;
}
int _tmain(int argc, _TCHAR* argv[])
{
HMODULE resContainer=LoadLibraryEx(L"ResourceDll.dll",NULL, LOAD_LIBRARY_AS_DATAFILE);
LPTSTR msg = GetResourceStr(resContainer,101);
std::wcout<<msg<<std::endl;
//Expected output: stringggg
//The output that i get: stringgggstring 102 string 103
int i = 0;
std::cin>>i;
return 0;
}
我应该在我的代码中更改什么以获得 预期输出 - stringggg? 为什么会这样? LoadString 是否为其从资源中读取的字符串分配了内存,或者我只是得到了指向内存中字符串已存储位置的指针? 感谢您的帮助!!
nBufferMax [in]
Type: int
The size of the buffer, in characters. The string is truncated and null-terminated if it is longer than the number of characters specified. If this parameter is 0, then lpBuffer receives a read-only pointer to the resource itself.
所以直接回答你的问题,你只是得到一个指向存储资源的内存的指针。
但是字符串资源不是以 null 结尾的(有关详细信息,请参阅 here),所以这就是您获得该输出的原因。 LoadString 的 return 值告诉您单个字符串资源的长度。如果您需要字符串以 null 结尾,则必须将字符串复制到单独的缓冲区,如下所示:
WCHAR* pszString;
int iLength = ::LoadString(
resContainer,
resourceID,
reinterpret_cast<LPWSTR>(&pszString),
0
);
WCHAR* pszString2 = new WCHAR[iLength + 1];
::StringCchCopyN(pszString2, iLength + 1, pszString, iLength);
或者,您可以调用 LoadString,将指向缓冲区的指针(而不是指向指针的指针)作为第 3 个参数,并将缓冲区的长度作为第 4 个参数,这会将字符串资源复制到缓冲区并以 null 终止它。缺点是如果你传的长度不够大,字符串会被截断,而且没办法提前查询到资源的长度。