C # взаимодействие с XPCOM - PullRequest
       4

C # взаимодействие с XPCOM

1 голос
/ 12 октября 2010

Прежде чем задать свой вопрос, я должен признать, что мои знания о взаимодействии .NET редки, поэтому я понимаю, что, возможно, я делаю ошибку новичка.

Я использую GeckoFx библиотека для создания приложения C #, содержащего встроенный экземпляр браузера Gecko (Firefox).Приложение работает хорошо, используя GeckoFx в его первоначальном виде, но мне нужно расширить его для поддержки запросов XPath, используя интерфейс Mozilla nsIDOMXPathEvaluator.

База кода 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 для оценки выражения XPath в контексте загруженного 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);

Хотя первые три переменные заполнены правильно, вызов Evaluate завершается неудачно с исключением «Попытка чтения или записи в защищенную память».Я склонен полагать, что проблема заключается в способе строковых значений моего кода маршалов, поскольку я видел различные сообщения об исключениях при экспериментировании с маршаллированным типом параметра выражения.

Кажется, я не единственныйчеловек, страдающий этой проблемой, как показано в этом сообщении на форуме , но я не могу понять, чем моя реализация отличается от многих других рабочих примеров в библиотеке GeckoFx.

Любые идеи будут высоко оценены.

Спасибо, Тим.

1 Ответ

2 голосов
/ 17 октября 2010

Здесь 2 вопроса.

1) Вам не хватает аргумента в методе nsIDOMXPathEvaluator.Evaluate. Вам нужен аргумент nsISupports, который можно использовать для сбора результата (фактически nsIDOMXPathResult), если вы не хотите создавать новый объект 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);

И теперь вы не должны испытывать никаких исключений, и результат должен быть действительным. Но то, что вы делаете с результатом, будет другим вопросом. Вам нужно будет реализовать несколько других интерфейсов, чтобы широко его использовать, но это должно привести вас на правильный путь.

Приветствия

...