Я новичок в 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 память для строки, которую он прочитал из ресурсов, или я только что получил указатель на место в памяти, где строка уже сохранена?
Спасибо за вашу помощь!!
Документация LoadString говорит:
nBufferMax [in]
Тип: int
Размер буфера, в символах. Строка усекается и завершается нулем, если она длиннее указанного количества символов. Если этот параметр равен 0, то lpBuffer получает доступный только для чтения указатель на сам ресурс.
Таким образом, чтобы ответить на ваш вопрос напрямую, вы просто получите указатель на память, где хранится ресурс.
Но строковый ресурс не заканчивается нулем (для получения дополнительной информации см. Вот), так вот почему вы получаете этот вывод. Возвращаемое значение LoadString сообщает вам длину отдельного строкового ресурса. Если вам нужна строка с нулевым символом в конце, вам нужно скопировать строку в отдельный буфер, например так:
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- прекратить это. Недостатком является то, что строка будет обрезана, если вы не передадите достаточно большую длину, и нет способа предварительно запросить длину ресурса.
Других решений пока нет …