私は VB6 を使用して ActiveX EXE の作成に取り組んでおり、得られた唯一の例はすべて Delphi で書かれています。
サンプル コードを読んで、署名の後にsafecallキーワードが続く関数がいくつかあることに気付きました。次に例を示します。
function AddSymbol(ASymbol: OleVariant): WordBool; safecall;
このキーワードの目的は何ですか?
私は VB6 を使用して ActiveX EXE の作成に取り組んでおり、得られた唯一の例はすべて Delphi で書かれています。
サンプル コードを読んで、署名の後にsafecallキーワードが続く関数がいくつかあることに気付きました。次に例を示します。
function AddSymbol(ASymbol: OleVariant): WordBool; safecall;
このキーワードの目的は何ですか?
さらに、例外ファイアウォールは、IErrorInfo をサポートするオブジェクトで SetErrorInfo() を呼び出すことによって機能するため、呼び出し元は例外に関する拡張情報を取得できます。これは、TComObject と TAutoIntfObject の両方で TObject.SafeCallException オーバーライドによって行われます。これらの型は両方とも、この事実を示すために ISupportErrorInfo も実装しています。
例外が発生した場合、safecall メソッドの呼び出し元は ISupportErrorInfo を照会し、メソッドが失敗した HRESULT (上位ビット セット) のインターフェイスを照会し、それが S_OK を返す場合、GetErrorInfo()は例外情報を取得できます (説明、ヘルプなど、SafeCallException オーバーライドで Delphi RTL によってSetErrorInfo()に渡された IErrorInfo 実装の形式で)。
Safecall は、パスカルまたはレジスター (デフォルト) を左から右に渡すのではなく、右から左にパラメーターを渡します。
safecall を使用すると、プロシージャまたは関数は、戻るときにスタックからパラメーターを削除します (pascal と同様ですが、呼び出し元次第である cdecl とは異なります)。
Safecall は例外「ファイアウォール」を実装しています。特に Win32 では、これはプロセス間 COM エラー通知を実装します。それ以外の場合は、stdcall (win API で使用される他の呼び出し規約) と同じです。
Francoisが言ったことと、safecallがなかった場合、COMメソッドの呼び出しは次のようになり、例外を取得する代わりに独自のエラーチェックを実行する必要があります。
function AddSymbol(ASymbol: OleVariant; out Result: WordBool): HResult; stdcall;