Что такое safecall?
Я работаю над созданием ActiveX EXE с помощью VB6, и единственный пример, который я получил, написан на Delphi.
Читая код примера, я заметил, что есть некоторые функции, чьи подписи следуют ключевому слову safecall. Вот пример:
function AddSymbol(ASymbol: OleVariant): WordBool; safecall;
Какова цель этого ключевого слова?
Ответы
Ответ 1
Safecall передает параметры справа налево, вместо паскаля или регистра (по умолчанию) слева направо
С помощью safecall процедура или функция удаляет параметры из стека при возврате (например, pascal, но не как cdecl, где это относится к вызывающему)
Safecall реализует "брандмауэры" исключения; esp на Win32, это реализует сообщение об ошибке COM-запроса interprocess. В противном случае он был бы идентичен stdcall (другое соглашение о вызове, используемое с win api)
Ответ 2
Кроме того, брандмауэры исключения работают, вызывая SetErrorInfo() с объектом, который поддерживает IErrorInfo, так что вызывающий может получить расширенную информацию об исключении. Это выполняется переопределением TObject.SafeCallException как в TComObject, так и в TAutoIntfObject. Оба эти типа также используют ISupportErrorInfo, чтобы отметить этот факт.
В случае исключения вызывающий метод safecall может запрашивать для ISupportErrorInfo, затем запрашивать для интерфейса, метод которого привел к ошибке HRESULT (высокий бит), и если это возвращает S_OK, GetErrorInfo() может получить информацию об исключении (описание, справку и т.д.) в виде реализации IErrorInfo, которая была передана SetErrorInfo() в Delphi RTL в переопределении SafeCallException).
Ответ 3
Что сказал Франсуа, и если бы это не было для safecall, ваш вызов COM-метода выглядел бы как показано ниже, и вам придется делать свою собственную проверку ошибок вместо того, чтобы получать исключения.
function AddSymbol(ASymbol: OleVariant; out Result: WordBool): HResult; stdcall;