2010-10-12 168 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