В качестве примера рассмотрим EnumWindowStations()
, для которого требуется вызывающая сторона передает функцию обратного вызова EnumWindowStationsProc()
. Функция обратного вызова будет вызываться один раз для каждой оконной станции в текущем терминальном сеансе. Давайте посмотрим на сигнатуру функции обратного вызова:
BOOL CALLBACK EnumWindowStationProc(
_In_ LPTSTR lpszWindowStation,
_In_ LPARAM lParam
);
Первый параметр — это указатель на строковые данные. Был ли этот строковый буфер выделен явно для вызова обратного вызова, и будет ли он освобожден сразу после возврата обратного вызова или, возможно, непосредственно перед возвратом функции перечисления? Или указатель указывает на какую-то постоянную память, так что строковый буфер останется выделенным и пригодным для использования после этого?
Это важный момент, потому что, если он не постоянный, то было бы неправильно, например, хранить необработанный указатель в глобальном контейнере для доступа после завершения обратного вызова и полного процесса перечисления. Вместо этого было бы необходимо скопировать базовые строковые данные в буфер, управляемый приложением, до обратного вызова.
Официальная документация, похоже, не дает ясного представления о времени жизни строковых данных. В описании параметра всего одна строка:
lpszWindowStation [in]
Имя оконной станции.
И нигде на странице документации не говорится о времени жизни строковых данных. Я также не могу припомнить, чтобы когда-либо находил страницу MSDN, которая отвечает на этот вопрос «раз и навсегда», то есть для всех случаев использования идиомы обратного вызова в Windows API.
На данный момент меня больше всего интересует случай EnumWindowStations()
/EnumWindowStationsProc()
, но было бы лучше, если бы отвечающие обращались к общему случаю, то есть к тому, что следует предполагать для всех функций обратного вызова Windows API.