Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Всем привет J>хотел/в сомнениях/.. вставить это себе в "учебный проект" код очень сомнительный J>покритикуйте/научите как надо по нормальному
код действительно имеет кучу проблем:
излишняя зависимость от монолитного windows.h с грязными макросами
макросы, со всеми вытекающими, особенно, при возможности их убрать
шаблоны, которые имеют лишь одно инстанциирование
FormatMessage уже является макросом, не нужно было руками писать #ifdef _UNICODE
класс называется глаголом, что может привести к неправильному использованию
слишком много магии
сырые указатели со всеми вытекающими
C-форматирование со всеми вытекающими (обрезание сообщения, отсутствие проверки типов и тд)
лишняя зависимость от Loki (нашли куда его засунуть, прямо жить не можем без него)
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, jyuyjiyuijyu, Вы писали:
J>>Всем привет J>>хотел/в сомнениях/.. вставить это себе в "учебный проект" код очень сомнительный J>>покритикуйте/научите как надо по нормальному U>код действительно имеет кучу проблем:
U>
U> излишняя зависимость от монолитного windows.h с грязными макросами U> макросы, со всеми вытекающими, особенно, при возможности их убрать U> шаблоны, которые имеют лишь одно инстанциирование U> FormatMessage уже является макросом, не нужно было руками писать #ifdef _UNICODE U> класс называется глаголом, что может привести к неправильному использованию U> слишком много магии U> сырые указатели со всеми вытекающими U> C-форматирование со всеми вытекающими (обрезание сообщения, отсутствие проверки типов и тд) U> лишняя зависимость от Loki (нашли куда его засунуть, прямо жить не можем без него) U>
излишняя зависимость от монолитного windows.h с грязными макросами
все равно windows.h через stdafx.h включен во всем проекте это винапи
проект в основном поэтому без него никак нельзя макросы, со всеми вытекающими, особенно, при возможности их убрать
согласен макросы сакс но тут вроде всего один и имя не перепутаеш ни с кем
а как еще разрулить юникод/анси ? шаблоны, которые имеют лишь одно инстанциирование
не понял про что Вы можно поподробнее ? FormatMessage уже является макросом, не нужно было руками писать #ifdef _UNICODE
так я не из за FormatMessage класс то один я его настраиваю через макрос класс называется глаголом, что может привести к неправильному использованию
согласен я бы тоже не понял чужой код с таким названием
но являющийся классом слишком много магии
как бы вы переписали ? сырые указатели со всеми вытекающими
тут вроде они не доставляют проблем все буферы автоматические C-форматирование со всеми вытекающими (обрезание сообщения, отсутствие проверки типов и тд)
согласен впринципе он отстойно себя ведет с сипипи типами но с базовыми и с обычными
си строками сносно да и это просто привычка еще а так да сакс в сипипи лучше сразу привыкать к "коут" лишняя зависимость от Loki (нашли куда его засунуть, прямо жить не можем без него)
вот это тоже мало опыта с шаблонами можно сказать что нету я потом уже когда написал
подумал что можно было просто перегрузить через char wchar_t но вот если бы
были такие типы которые занимают много памяти то это бы очень сэкономило память ?
считай мы бы обменяли на пу4стой тип сохранив уникальность и матчинг
Здравствуйте, uzhas, Вы писали: излишняя зависимость от монолитного windows.h с грязными макросами
сложилось так что все основные заголовки включены в stdafx.h
а он включен почти во все .cpp файлы вот этот файл тут и без
windows.h мама дорогая сколько макросов представить страшно
но тьфу тьфу тьфу пока обходится но бывает что бахает в самых неожиданных
местах правда в других проектах при других обстоятельствах
Здравствуйте, jyuyjiyuijyu, Вы писали: J>как бы вы переписали ?
для начала надо определеиться, что выдается клиентам, то есть что является интерфейсом к нашей функциональности. когда все в одном хедере, то довольно тяжело это понять
либо это GetWin32Error, либо GetWin32ErrorA + GetWin32ErrorW. обычно приложение либо полностью ANSI, либо юникодное и как раз #ifdef _UNICODE используют для понимания в каком режиме нас собирают.
далее надо продумать названия, чтобы они были ясны
//windows_merror_message.h#pragma once
#include <cstdint>
#include <cstring>
namespace Windows
{
std::string GetErrorMessageA();
std::string GetErrorMessageA(int32_t errorCode);
std::wstring GetErrorMessageW();
std::wstring GetErrorMessageW(int32_t errorCode);
}
в одном файле я попытался определить лишь то, что реально интересно будет читать клиенту. все подробности реализации мы перемещаем в .cpp.
если вам в программе не нужно перемешивать юникодные и не юникодные функции, то я бы определил в отдельном файле строку и заюзал бы ее
Скрытый текст
//windows_string.h#pragma once
#include <cstring>
namespace Windows
{
#ifdef _UNICODE
typedef std::wstring String;
#else
typedef std::string String;
#endif
}
//windows_merror_message.h#pragma once
#include"windows_string.h"namespace Windows
{
String GetErrorMessage();
String GetErrorMessage(int32_t errorCode);
}
для форматирования сообщений можно использовать более высокоуровневые средства типа (w)stringstream
использовать C-функции лично я предпочитаю только когда душа болит за перформанс
переделал так перегрузив по char wchar_t все равно они все перед помещением
в стек расширяются до 32 бит movsx eax, byte ptr [ebp — 1] push eax
но вот что хочется убрать так это создание фейкового chType() только для того
чтоб выбрать функцию хочется чтоб все в компайл тайм разрулилось без отражения
на результирующий код знаю в релизе да с оптимизацией все будет как нельзя лучше
и функций то таких не будет не говоря уже про переменные но живем то мы в режиме
отладки а это лишний step over не говоря уже про замусоривание кода
как бы так выбрать функцию полностью в компайл тайм без chType() ?
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, jyuyjiyuijyu, Вы писали:
J>>как бы вы переписали ? U>для начала надо определеиться, что выдается клиентам, то есть что является интерфейсом к нашей функциональности. когда все в одном хедере, то довольно тяжело это понять U>либо это GetWin32Error, либо GetWin32ErrorA + GetWin32ErrorW. обычно приложение либо полностью ANSI, либо юникодное и как раз #ifdef _UNICODE используют для понимания в каком режиме нас собирают.
все так но часто надо в анси проекте или наоборот заюзать
отличную от настроек проекта функцию приходится явно писать суффиксы A or W
поэтому я сделал для настрок проекта по умолчанию через макрос
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>интересно посмотреть на правильное решение этой задачи J>код кто нибудь может написать хороший так как должно было бы быть у меня ?
Во-первых, GetLastError — это обработка ошибок. Следовательно, должен быть exception.
Во-вторых, исключение должно наследоваться, прямо или косвенно, от std::exception. Интерфейс std::exception предполагает, что текст сообщения есть строка из char’ов. То есть получать его будем через FormatMessageA. Это, кстати, снимает все вопросы о зависимости от _UNICODE.
В-третьих, нет ничего хуже, чем получить от пользователя багрепорт с сообщениями на клингонском или древнеэльфийском. Поэтому диагностические сообщения в исключениях должны быть на английском языке. Поэтому «DWORD dwLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);» — это вроде бы правильно, но надо проверять.
И наконец, я в подобных случаях добавляю функцию для проверки результатов вызова функций API:
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>интересно посмотреть на правильное решение этой задачи J>код кто нибудь может написать хороший так как должно было бы быть у меня ?