質問

次のように始まるCOM構造を参照しています:

[scriptable, uuid(ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e)]
interface nsICacheSession : nsISupports
{
    /**
     * Expired entries will be doomed or evicted if this attribute is set to
     * true.  If false, expired entries will be returned (useful for offline-
     * mode and clients, such as HTTP, that can update the valid lifetime of
     * cached content).  This attribute defaults to true.
     */
    attribute PRBool doomEntriesIfExpired;
...

出典:http ://dxr.proximity.on.ca/dxr/mozilla-central/netwerk/cache/public/nsICacheSession.idl.html#58

そのインターフェイスをC#アプリにインポートするコードを見つけました。ただし、 set メソッドは役に立たないようであり、何が起こるかを確認するためだけに呼び出すとエラーがスローされるため、コードは間違っている必要があります。

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{
    [return: MarshalAs(UnmanagedType.Bool)]
    void set_doomEntriesIfExpired();
    [return: MarshalAs(UnmanagedType.Bool)]
    bool get_doomEntriesIfExpired();
...

doomEntriesIfExpired の値を設定する正しい方法と、コードからこれを参照するにはどうすればよいですか

編集

コードを次のように変更し、" System.AccessViolationException:保護されたメモリの読み取りまたは書き込みを試行しましたyada yada ...":

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{
    void set_doomEntriesIfExpired(bool enabled);
    bool get_doomEntriesIfExpired();
...
役に立ちましたか?

解決

挿入した答えは良いです。 COMでは、InteropブールはデフォルトでVARIANT_BOOLとしてマーシャリングされるため、MarshalAs属性を追加してマーシャラーに標準の4バイトBOOL型を使用するように指示することは正しいですが、式のゲッター部分にも属性を追加する必要があります。

一般に、インターフェイスで定義されているプロパティをゲッターとセッターに分割するのではなく、プロパティのままにしておきます。インターフェース定義のセマンティクスとよりよく一致し、通常は読みやすくなります。 doomEntriesIfExpiredの属性の性質を保持するために、次のようにCOMインポート定義を書き直すことができるはずです。

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, 
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{

    bool doomEntriesIfExpired 
    { 
        [param:MarshalAs(UnmanagedType.Bool)]set; 
        [return:MarshalAs(UnmanagedType.Bool)]get; 
    }

...

他のヒント

void set メソッドに対して [return:MarshalAs(UnmanagedType.Bool)] を記述しているという事実は、明らかにエラーの原因です。

とはいえ、.idlに[return ...]タグを付けずにC ++ mozillaプラグインをコーディングできました。例:

[scriptable, uuid(ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e)]
interface nsICacheSession : nsISupports
{
    void set_doomEntriesIfExpired(in bool value);
    bool get_doomEntriesIfExpired();
}

ところで、C#でnsiプラグインをコーディングしてもいいですか?

答えは次のとおりでした:

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{
    void set_doomEntriesIfExpired([In, MarshalAs(UnmanagedType.Bool)] ref bool enabled);
    bool get_doomEntriesIfExpired();
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top