2010-10-12 92 views
1

在问我的问题之前,我应该承认我对.NET互操作的知识很少,所以我意识到我可能会犯一个新手错误。C#与XPCOM互操作

我正在使用GeckoFx库创建一个包含嵌入式Gecko(Firefox)浏览器实例的C#应用​​程序。该应用程序在原始格式中使用GeckoFx效果很好,但我需要使用Mozilla nsIDOMXPathEvaluator界面将其扩展为支持XPath查询。

的GeckoFx代码库包括曝光和使用基础托管壁虎接口的许多实例,我已经遵循相同的码型,以暴露了几个新的接口:

[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失败的前ception“尝试读取或写入受保护的内存。”我倾向于认为问题在于我的代码编组字符串值的方式,因为我在试验编组表达式参数的类型时看到了不同的异常消息。

看来我不是唯一遭受这个问题的人,如this forum post所示,但我无法理解我的实现与GeckoFx库中的其他许多工作示例的不同之处。

任何想法将不胜感激。

谢谢, Tim。

回答

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

现在你不应该经历任何异常,结果应该是有效的。但你对结果的处理将是另一回事。你需要实现一些其他接口来充分利用它,但这应该让你走上正确的道路。

干杯

+0

非常感谢你 - 你的回答是完全正确的。我更正了代码中的两个错误,并添加了nsIDOMXPathResult的接口定义,现在我可以检索节点结果并使用它来初始化一个新的GeckoNode实例。再次感谢。 – 2010-10-17 20:04:01