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<nsIDOMWindow> 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 中,但随后无法注册其类