Before asking my question, I should admit that my knowledge of .NET interop is sparse, so I realize that I might be making a newbie error.
I am using the GeckoFx library to create a C# application that contains an embedded Gecko (Firefox) browser instance. The app works well using GeckoFx in its original form, but I need to extend it to support XPath queries, using the Mozilla nsIDOMXPathEvaluator
interface.
The GeckoFx codebase includes numerous examples of exposing and using the underlying managed Gecko interfaces, and I have followed the same code patterns to expose several new interfaces:
[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);
}
With the new interfaces exposed, I attempt to use nsIDOMXPathEvaluator
to evaluate an XPath expression in the context of the loaded DOM:
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);
Although the first three variables are correctly populated, the call to Evaluate
fails with an exception "Attempted to read or write protected memory.". I am inclined to believe that the problem lies in the way my code marshals string values, as I have seen different exception messages when experimenting with the marshalled type of the expression parameter.
It seems that I am not the only person suffering this problem, as shown in this forum post, but I cannot understand how my implementation differs from the many other working examples in the GeckoFx library.
Any ideas would be greatly appreciated.
Thanks, Tim.