Как преобразовать исключения в ошибки и сообщения об ошибках при переносе API классов C++ для потребления C?
Эта проблема
Скажем, у вас есть класс C++.
Скажем, вы хотите экспортировать его конструктор (ы) и методы в C.
Допустим, вы следовали советам, данным в решении вопроса " Оборачивание API класса C++ для потребления C".
Теперь предположим, что ваш конструктор класса может выдать одно или несколько исключений, которые вы хотите перехватить на стороне C++, прежде чем вернуться в мир C, в то же время предоставляя пользователю C возможность получить информацию об ошибке, которая только что произошла.
Первый подход
Я мог бы проверить это MyClass_new()
вернул нулевой указатель, а затем получил "последнее сообщение об ошибке", произошедшее в библиотеке с функцией, но когда конструктор завершился неудачей, просто не было объекта, обеспечивающего правильный контекст для извлечения ошибки, поэтому для хранения объекта должна использоваться глобальная переменная последняя ошибка, которая, однако, подрывает повторное появление библиотеки.
Второй подход
Еще одна возможность, о которой я могу подумать, - это фактически решение, которое я придумал, - чтобы класс перехватил исключение внутри самого конструктора, преобразовал его в сообщение об ошибке и поместил объект в "состояние ошибки" своего рода.
После каждого
MyClass myObj = MyClass_new();
следующая проверка будет выполнена
if (MyClass_isInErrorState(myObj))
и сообщение об ошибке будет получено с помощью следующего оператора
const char *error = MyClass_getLastError(myObj);
Третий подход
Еще одна возможность, о которой я могу подумать, - это передать указатель на буфер заданного размера каждой функции, которая может дать сбой, которая будет заполнена сообщением об ошибке, но это выглядит грязно.
Как бы вы это сделали? Существует ли де-факто стандартный способ решения таких вопросов?
1 ответ
Отвечая на мой собственный вопрос.
Я думаю, что я пойду с немного измененным вторым подходом.
Конструктор вернется BOOL
как и все другие функции, которые могут выйти из строя и примут MyClass *
выходной параметр, который будет установлен в какое-либо значимое значение даже в случае ошибки, так что MyClass_getLastError(myObj)
может быть использован.
Это избавляет от лишнего MyClass_isInErrorState()
функция.
MyClass
на стороне C будет непрозрачный указатель, а на стороне C++ будет указатель на структуру, содержащую указатель, возможно, NULL, на объект класса и своего рода буфер, содержащий строку ошибки.