Firefox 6:XPCOM 组件中的 QueryInterface(nsIDOMWindow::GetIID() 问题,用于从 js 传递的浏览器内容窗口

Posted

技术标签:

【中文标题】Firefox 6:XPCOM 组件中的 QueryInterface(nsIDOMWindow::GetIID() 问题,用于从 js 传递的浏览器内容窗口【英文标题】:Firefox 6 :Problem with QueryInterface(nsIDOMWindow::GetIID() in XPCOM component, for browser content window passed from js 【发布时间】:2011-08-22 12:37:37 【问题描述】:

我正在努力为我在 Mac OS 上的插件添加对 Firefox 6 的支持,其中以下逻辑在 Firefox 4.5 版本中有效,但在 Firefox 6 中失败。

XPCOM 组件具有IObserverClient 的子类,并将其自身添加为自定义事件的观察者。 此自定义事件是从浏览器 overlay.js 发布的,传递所选浏览器的内容窗口。

var observerService = Components.classes["@mozilla.org/observer-service;1"]
                                .getService(Components.interfaces.nsIObserverService);
if (observerService) 
    var data =  gBrowser.selectedBrowser.contentWindow.location.href;

    observerService.notifyObservers(gBrowser.selectedBrowser.contentWindow, JSEventTopic, data);

在XPCOM组件处理程序中,试图从nsISupports获取nsIDOMWindow接口

void XXX::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)

    nsCOMPtr<nsIDOMWindow> pWin;
    aSubject->QueryInterface(nsIDOMWindow::GetIID(), getter_AddRefs(pWin));

问题是,对于 Firefox 6,pWin 为零。在 Firefox 4 和 5 中,pWin 符合预期,而不是 nil。

【问题讨论】:

这不太可能与您的问题有关,但您应该考虑使用do_QueryInterface:nsCOMPtr&lt;nsIDOMWindow&gt; pWin(do_QueryInterface(pSubject)); 我注意到您的Observe 函数使用了参数名称aSubject,但函数内部的代码使用了pSubject。这可能只是一个复制粘贴错误,也可能是您的实际代码中的一个严重问题。 感谢指出,是帖子复制粘贴错误。 【参考方案1】:

直接的问题似乎是,作为aSubject 传递的任何对象都没有实现nsIDOMWindow 接口,这自然会导致QueryInterface 失败并产生null。你不能 QI 一个对象到一个它没有实现的接口,你也不能 QI null 到任何东西。

我不知道是什么导致了这种变化,但这里有几件事可以帮助您找到真正的问题:

确保您接收的主题不为空,并且您尝试 QI 的指针是侦听器方法接收的参数。 在您的 javascript 代码中,检查您传递的窗口对象是否为 nil,并且实际上应该实现 nsIDOMWindow。 检查aTopic 是否包含您期望的值,而不是其他一些事件字符串。

【讨论】:

看起来代码没有任何问题。我无法完全弄清楚是什么解决了这个问题,但是删除这个 dylib 的 binarycomponent 指令已经解决了这个问题。使用 chrome.manifest(binary-component components/XXX5.dylib appversion>=5.0,binary-component components/XXX6.dylib appversion>=6.0 ) 中指定的 binarycomponent 指令,因为两者都适用于 FF6 dylib 的 ver5 和 6 正在加载,尽管正确的 dylib 的代码正在被执行。(从组件中删除 FF5dylib,它可以工作)。这个 dylib 的正确版本被加载了另一个 dylib,因此不需要在 chrome 中输入。【参考方案2】:

我对插件开发不太熟悉。但这适用于我的应用程序(C++)。

nsCOMPtr<nsIDOMWindow> domWindow; 
nsresult rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));

nsCOMPtr<nsIDOMWindowUtils> windowUtils(do_GetInterface(domWindow)); 

【讨论】:

以上是关于Firefox 6:XPCOM 组件中的 QueryInterface(nsIDOMWindow::GetIID() 问题,用于从 js 传递的浏览器内容窗口的主要内容,如果未能解决你的问题,请参考以下文章

帮我创建一个 Firefox 扩展(Javascript XPCOM 组件)

XPCOM 组件 DLL 加载到 Firefox 中,但随后无法注册其类

XPCOM 的 XPI 扩展

如何从 javascript xpcom 组件中使用 c++ xpcom 组件

注册 XPCOM 组件时出现问题

c++ XPCOM组件与COM服务之间的通信(IPC)