1

質問をする前に、.NET相互運用に関する知識が乏しいことを認める必要があります。そのため、初心者のミスを犯している可能性があることに気づきました。

GeckoFxライブラリを使用して、埋め込まれたGecko(Firefox)ブラウザーインスタンスを含むC#アプリケーションを作成しています。このアプリは、元の形式のGeckoFxを使用して正常に動作しますが、MozillansIDOMXPathEvaluatorインターフェイスを使用して、XPathクエリをサポートするように拡張する必要があります。

GeckoFxコードベースには、基盤となるマネージドGeckoインターフェイスを公開および使用する例が多数含まれています。同じコードパターンに従って、いくつかの新しいインターフェイスを公開しました。

[Guid("75506f8a-b504-11d5-a7f2-ca108ab8b6fc"),
    ComImport,
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsIDOMXPathEvaluator
{
    nsIDOMXPathExpression CreateExpression(
        [MarshalAs(UnmanagedType.LPWStr)] string expression,
        nsIDOMXPathNSResolver resolver);

    nsIDOMXPathNSResolver CreateNSResolver(
        nsIDOMNode nodeResolver);

    nsISupports Evaluate(
        [MarshalAs(UnmanagedType.LPWStr)] string expression,
        nsIDOMNode contextNode,
        nsIDOMXPathNSResolver resolver,
        ushort type);
}

[Guid("ce600ca8-e98a-4419-ad61-2f6d0cb0ecc8"),
    ComImport,
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsIDOMXPathExpression
{
    nsISupports Evaluate(
        nsIDOMNode contextNode,
        ushort type,
        nsISupports result);
}

[Guid("75506f83-b504-11d5-a7f2-ca108ab8b6fc"),
    ComImport,
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsIDOMXPathNSResolver
{
    string LookupNamespaceUri(
        [MarshalAs(UnmanagedType.LPWStr)] string prefix);
}

新しいインターフェイスを公開しnsIDOMXPathEvaluatorた状態で、ロードされたDOMのコンテキストでXPath式を評価するために使用しようとします。

var evaluator = Xpcom.CreateInstance<nsIDOMXPathEvaluator>("@mozilla.org/dom/xpath-evaluator;1");
var node = (nsIDOMNode)Document.DocumentElement.DomObject;
var resolver = evaluator.CreateNSResolver(node);
var result = evaluator.Evaluate("//div[0]", node, resolver, 0);

最初の3つの変数は正しく入力されていますが、の呼び出しはEvaluate「保護されたメモリの読み取りまたは書き込みを試みました」という例外を除いて失敗します。マーシャリングされたタイプの式パラメーターを試したときにさまざまな例外メッセージが表示されたため、コードが文字列値をマーシャリングする方法に問題があると考える傾向があります。

このフォーラムの投稿に示されているように、この問題に苦しんでいるのは私だけではないようですが、私の実装がGeckoFxライブラリの他の多くの実用的な例とどのように異なるかを理解できません。

任意のアイデアをいただければ幸いです。

ありがとう、ティム。

4

1 に答える 1

2

ここには 2 つの問題があります。

1) nsIDOMXPathEvaluator.Evaluate メソッドに引数がありません。新しい nsIDOMXPathResult オブジェクトを作成したくない場合は、結果 (実際には nsIDOMXPathResult ) を収集するために使用できる nsISupports 引数が必要です。

2) これらのインターフェースは、そのようにマーシャリングできる通常の文字列を使用しません。たとえば、 nsIDOMXPathEvaluatorのドキュメント ページを見ると、evaluate が string や wstring ではなく DOMString を取ることがわかります。GeckoFx では、DOMString に nsAString を使用できます。

したがって、nsIDOMXPathEvaluator.Evaluate は次のようになります。

nsISupports Evaluate(
    nsAString expression,
    nsIDOMNode contextNode,
    nsIDOMXPathNSResolver resolver,
    ushort type, nsISupports result );

nsIDOMXPathNSResolver.LookupNamespaceUri は次のようになります。

nsAString LookupNamespaceUri( nsAString prefix );

これで、次のことができるはずです。

var evaluator = Xpcom.CreateInstance<nsIDOMXPathEvaluator>("@mozilla.org/dom/xpath-evaluator;1");
var node = (nsIDOMNode)Document.DocumentElement.DomObject;
var resolver = evaluator.CreateNSResolver(node);
var result = evaluator.Evaluate(new nsAString(@"//div[0]"), node, resolver, 0, null);

これで例外は発生せず、結果は有効になるはずです。しかし、その結果をどうするかは別問題です。それを最大限に活用するには、他のいくつかのインターフェースを実装する必要がありますが、それで正しい道を歩むことができます。

乾杯

于 2010-10-17T08:48:21.980 に答える