Monday, March 31, 2008

XPCOM Proxy and getting access to the GUI from non-GUI thread

It was a frustrating week of pulling out hair trying to get this to work.

First, you'll need to get nsIProxyObjectManager which is not part of the Gecko-sdk but the idl file is part of the Firefox source code. So download the Firefox source code for the Firefox version that you're using. If you are using Firefox 2.0, downloading Firefox 3.0 source code and using the idl included there will not suffice. The UID of the IDL in Firefox 3.0 is different from that of Firefox 2.0. It would've saved me half a week of frsutration had I realized this sooner.

I'm sure there are several ways to proceed from here. I found the IDL in the Firefox source, generated a header file out of it using the xpidl command from Gecko-sdk and included that in my project. You'll find that when you try to compile your project with the nsIProxyObejctManager.h inculded, it'll require other header files as well and so you'll have to find and generate header files from a few other IDLs as well. I think in total it comes out to about 10. Not too frustrating a process, but frustrating enough.

Finally, you'll need to access the method you want via the proxy
Declare the proxy object
nsCOMPtr pmgr;
pmgr=do_GetService("@mozilla.org/xpcomproxy;1",&rv);

Now, i'm trying to write to an RDF file via the proxy. So I'll declare an RDF datasource to access via the proxy
nsCOMPtr proxyObject;

And then try to get proxy access to the nsIRDFDataSource
if (pmgr){
rv = pmgr->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIRDFDataSource), dsource, 1|4, getter_AddRefs(proxyObject));

Now we have a proxy object for calling all functions declared in nsIRDFDataSource. For instance, to call the assert, we would do
proxyObject->Assert(ns_subject, ns_predicate, ns_literal, PR_TRUE);

Its the same for any other XPCOM Interface. You'll need to get access to it via GetProxyForObject and then you can access all functions to it via the proxy as above. Hope this helped.

Sunday, March 16, 2008

XPCOM and OS X

What I had to do to get an XPCOM component written in C++ compiled and linked on OS X
1. Install Xcode
2. Install Fink
3. At command prompt
cd /sw/bin;
sudo ./apt-get install glib
sudo ./apt-get install libIDL2
sudo cp libIDL-config-2 libIDL-config

4. Download the source of the Firefox version you'll be developing for. The only steps I had to perform that weren't mentioned on
http://developer.mozilla.org/en/docs/Mac_OS_X_Build_Prerequisites
was to add the following directory to my path
/sw/bin

5. change to directory to which Firefox source was downloaded and run the following commands
cp ./obj-ff/dist/bin/libxpcom_core.dylib ./obj-ff/dist/sdk/bin
cp ./obj-ff/dist/bin/libplds4.dylib ./obj-ff/dist/sdk/bin
cp ./obj-ff/dist/bin/libplc4.dylib ./obj-ff/dist/sdk/bin

6. Follow the steps give in
http://rcrowley.org/2007/07/17/cross-platform-xpcom-a-howto/
with Makefile looking like this:

GECKO_SDK := /obj-ff/dist/sdk

DEFINE := -DXP_UNIX -DXP_MACOSX
all: xpt dylib
xpt:
$(GECKO_SDK)/bin/xpidl -m header -I$(GECKO_SDK)/idl foo.idl
$(GECKO_SDK)/bin/xpidl -m typelib -I$(GECKO_SDK)/idl foo.idl
impl:
g++ -w -c -o foo_impl.o -I $(GECKO_SDK)/include $(DEFINE) foo_impl.cpp
module:
g++ -w -c -o foo_module.o -I $(GECKO_SDK)/include $(DEFINE) foo_module.cpp
dylib: impl module
g++ -dynamiclib -o foo.dylib foo_impl.o foo_module.o -L$(GECKO_SDK)/lib \
-L$(GECKO_SDK)/bin -Wl,-executable_path,$(GECKO_SDK)/bin \
-lxpcomglue_s -lxpcom -lnspr4
clean:
rm *.o
rm foo.h
rm foo.xpt
rm foo.dylib

7. Run make. Hopefully, it should work.
  • Book reviews