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