Мне нужно написать C ++ API, который состоит из нескольких экспортированных классов C ++, предоставляемых из Dll, с использованием файлов .lib (MSVC). Из ответа на другой мой вопрос я понимаю, что экспортированные методы класса не могут использовать исключения, в случае, если C ++ API построен в одной версии VC ++ (скажем, 2010), а клиентский код написан в другой версии VC ++. Поскольку исключения не могут быть частью общедоступного интерфейса API, я ищу другую стратегию обработки ошибок. Мои ограничения: я не хочу использовать COM, и мне не хватает богатой системы кодов ошибок (например, HRESULT). Я хочу иметь класс, похожий на исключение, который содержит код ошибки, сообщение об ошибке и любую другую информацию, которая мне нужна. Кроме того, я не хочу делать отдельную сборку для каждой версии VC ++.
Мой текущий подход заключается в следующем. Каждый открытый метод класса возвращает перечисляемое значение (например, ErrorCode). В случае сбоя метода статическая функция, такая как GetLastErrorInfo, возвращает указатель на класс C ++ (скажем, ErrorInfo), который содержит информацию об ошибках досягаемости. ErrorInfo хранится как специфичные для потока данные и содержит информацию об ошибке последнего вызова в текущем потоке. Если последний вызов API завершился успешно, GetErrorInfo возвращает NULL.
Рассмотрим этот код с исключениями:
try
{
classPtr->DoSomething();
cout << classPtr->GetData() << endl;
}
catch(const MyException& ex)
{
cout << ex.GetErrorMessage() << endl;
return;
}
Без исключения это выглядит так:
ErrorCode result;
int data;
result = classPtr->DoSomething();
if ( result != Success )
{
cout << MyClass::GetLastErrorInfo()->GetErrorMessage() << endl;
return;
}
result = classPtr->GetData(data);
if ( result != Success )
{
cout << MyClass::GetLastErrorInfo()->GetErrorMessage() << endl;
return;
}
cout << data << endl;
Это не выглядит хорошо. Интерфейс класса запутан: у каждой функции теперь есть тип возврата ErrorCode. Возвращаемые значения становятся выходными параметрами. Есть ли лучший подход, позволяющий получать информацию об ошибках и поддерживать чистый интерфейс API?