Передача строк стандартной библиотеки в функции Win API

Передача строк стандартной библиотеки в функции Win API

При передаче строк стандартной библиотеки string и wstring в функции API в качестве параметров возникают некоторые проблемы.

Строка в качестве параметра должна передаваться в формате С-строки, т.е. как указатель char*. Это несложно исполнить с помощью функции c_str(), которая возвращает строку в стиле С с завершающим символом \0. Дополнительным препятствием является константность указателя на char*, которая легко преодолевается приведением к простому указателю. В результате передаваемый параметр выглядит так:
const_cast<char*>(s.c_str()). Это единственный способ непосредственной передачи строки в функцию API в качестве параметра. Однако, этот способ порождает неприятную проблему, которая заключается в том, что в дальнейшем эту строку становится невозможно обрабатывать средствами стандартной библиотеки. Если через десяток строк вашей программы, когда вы уже забыли, что передавали строку как параметр в функцию API, вы попытаетесь произвести с ней сложение, например str += "Петров", то результат будет непредсказуемый, обычно строка возвращается пустой, нельзя даже определить размер, результат нуль.

В классе CString библиотеки MFC есть функция освобождения буфера строки ReleaseBuffer(....), которую следует вызывать, что тоже можно забыть и иметь проблему. В стандартной библиотеке такой функции нет, как нет и описания решения этой проблеммы. Казалось бы можно из этой строки произвести другую, вызвав конструктор string snew(str), но и строка snew получается с тем же врожденным дефектом. Как оказалось проблема решается просто, нужно вызвать конструктор таким образом snew(str.c_str()) и использовать в дальнейшем новую строку. Про старую строку нужно забыть, возродить ее можно, только удалив символ конца строки из массива, обращаться к строке придется по индексу массива и в цикле находить конец строки, остальное можно не описывать.

Все эти изыскания пришлось провести, чтобы написать функцию форматирования аналогичную функции Format(....) из класса CString, подобия которой нет в стандартной библиотеке. Приходится каждый раз использовать функцию sprintf_s с соответствующим обрамлением или аналогичные не менее затратные функции. Код функции приведен ниже.

// возвращает строку отформатированую в стиле Format(....) из класса CString
// по умолчанию размер буфера равен размеру по умолчанию в библиотеке STL
string STLFormat(string format/*строка формата*/, int arc, const size_t szbuf = 15)
{

{
   string str;
   if(szbuf > 15) str.reserve(szbuf);
   sprintf_s(const_cast<char*>(str.c_str()),szbuf, const_cast<char*>(format.c_str()), arc);
   int sz = str.size();
   string s(str.c_str());
   return s;
}

[в начало]

Hosted by uCoz