|
2019/04/01(Mon) 10:09:02 編集(投稿者)
■No90644 (kuragefuwari さん) に返信 > DllImport属性で、PreserveSig=falseを指定することにより、戻り値のHRESULTがエラーとなった場合に、例外がスローされるようになるため、 > [DllImport("oleaut32.dll", PreserveSig=false)] > public static extern void LoadTypeLib([MarshalAs(UnmanagedType.LPWStr)]string fileName, out ITypeLib typeLib); > のように戻り値をintからvoidに変更できるところまでは理解できたのですが、そこからさらに > 第2引数の"out ITypeLib typeLib"を戻り値のほうに持ってこれる理由が理解できていません。
MSDN Library では、以下のように解説されていますね。 現行の機械翻訳だと読みにくいと思いますので、 人力翻訳されていた VS2008 当時の MSDN Library から引用します。 https://www.microsoft.com/ja-jp/download/details.aspx?id=20955
【PreserveSigAttribute 属性クラスの解説】
>> 既定では、タイプ ライブラリ エクスポータ (Tlbexp.exe) によって、HRESULT に S_OK を返す呼び出しは、 >> [out, retval] パラメータが関数の戻り値として使用されるように、変換されます。S_OK の HRESULT は破棄されます。 >> HRESULT が S_OK 以外の場合、共通言語ランタイムは例外をスローして、[out, retval] パラメータを破棄します。 >> PreserveSigAttribute をマネージ メソッドのシグネチャに適用した場合、属性が適用されたメソッドの >> マネージ シグネチャとアンマネージ シグネチャは同一になります。 >> >> メンバが複数の成功 HRESULT 値を返し、またその複数の値を検出する必要がある場合は、 >> 元のメソッドのシグネチャの保持が必要となります。ほとんどの COM メンバは HRESULT を 1 つ返すため、 >> PreserveSigAttribute を適用することによって、成功またはエラーの HRESULT を表す整数値を取得できます。 >> Tlbexp.exe はすべての [out, retval] パラメータをマネージ シグネチャに out パラメータとして保持します。 >> >> タイプ ライブラリ インポータ (Tlbimp.exe) もこの属性を適用します。Tlbimp.exe は、タイプ ライブラリを >> インポートするときにこの属性をディスパッチ インターフェイスに適用します。 >> >> メモ : >> COM からマネージ コードへの相互運用時に、マネージ コードが PreserveSigAttribute クラスで >> マークされていた場合、PreserveSigAttribute クラスでは、戻り値の Currency、Guid、および Object の型は >> サポートされません。これらの条件で、これらのいずれかの戻り値の型を PreserveSigAttribute クラスで >> 使用すると、TypeLoadException がスローされます。
【MarshalAsAttribute 属性クラスの PreserveSig フィールドの解説】
>> PreserveSig フィールドに true を設定すると、HRESULT 値または retval 値でアンマネージ シグネチャが直接変換されます。 >> false を設定すると、HRESULT 値または retval 値が自動的に例外に変換されます。既定では、PreserveSig フィールドは true です。 >> >> true の場合、結果として生成されるメソッド シグネチャは HRESULT 値を含む整数値を返します。 >> この場合、アプリケーション内で戻り値を手動で検査し、その結果に応じて対応する必要があります。 >> >> PreserveSig フィールドに false を設定すると、結果として生成されるメソッド シグネチャに含まれる戻り値の型は、 >> 整数型 (HRESULT) ではなく void 型になります。アンマネージ メソッドが HRESULT を生成した場合、ランタイムは >> 戻り値 S_OK (または 0) を自動的に無視し、例外をスローしません。S_OK 以外の HRESULT の場合、 >> ランタイムはその HRESULT に対応する例外を自動的にスローします。 >> DllImportAttribute 属性は、HRESULT を返すメソッドに対してこの変換を実行するだけです。 >> >> アプリケーションのエラー報告構造に例外が適している場合は、既定のエラー報告動作を HRESULT から例外に変更できます。 >> このフィールドは PreserveSigAttribute と似ていますが、PreserveSig フィールドとは異なり、この属性の既定値は false です。 >> >> 場合によっては、Visual Basic の開発者は、マネージ コードで DLL 関数を定義する際、 >> Declare ステートメントを使用する代わりに、DllImportAttribute を使用します。 >> PreserveSig フィールドの設定は、このような事例の 1 つです。
|