C#与XPCOM互操作
在问我的问题之前,我应该承认我对.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个问题。
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);
现在你不应该经历任何异常,结果应该是有效的。但你对结果的处理将是另一回事。你需要实现一些其他接口来充分利用它,但这应该让你走上正确的道路。
干杯
非常感谢你 - 你的回答是完全正确的。我更正了代码中的两个错误,并添加了nsIDOMXPathResult的接口定义,现在我可以检索节点结果并使用它来初始化一个新的GeckoNode实例。再次感谢。 – 2010-10-17 20:04:01