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);

尽管前三个变量已正确填充,但调用Evaluate失败并出现异常“尝试读取或写入受保护的内存。”。我倾向于认为问题在于我的代码编组字符串值的方式,因为我在尝试使用表达式参数的编组类型时看到了不同的异常消息。

似乎我不是唯一遇到此问题的人,如本论坛帖子所示,但我无法理解我的实现与 GeckoFx 库中​​的许多其他工作示例有何不同。

任何想法将不胜感激。

谢谢,蒂姆。

4

1 回答 1

2

这里有2个问题。

1)您在 nsIDOMXPathEvaluator.Evaluate 方法中缺少一个参数。如果您不想创建新的 nsIDOMXPathResult 对象,则需要一个可用于收集结果的 nsISupports 参数(实际上是一个 nsIDOMXPathResult )。

2) 这些接口不使用您可以通过这种方式编组的普通字符串。例如,如果您查看nsIDOMXPathEvaluator的文档页面,您将看到评估采用 DOMString 而不是字符串或 wstring。在 GeckoFx 中,您可以将 nsAString 用于 DOMString。

所以 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 回答