nsIComponentLoader is dead - long live nsIModuleLoader! Take the

opportunity to remove support for nsIComponentManagerObsolete, and
formalize a nice shutdown API.

Not part of the build.
This commit is contained in:
mhammond%skippinet.com.au 2005-12-19 05:05:45 +00:00
Родитель 1c9cd51aa9
Коммит 020e6179d4
14 изменённых файлов: 123 добавлений и 951 удалений

Просмотреть файл

@ -54,6 +54,7 @@ PYSRCS_XPCOM = \
file.py \ file.py \
nsError.py \ nsError.py \
register.py \ register.py \
shutdown.py \
xpcom_consts.py \ xpcom_consts.py \
xpt.py \ xpt.py \
$(NULL) $(NULL)

Просмотреть файл

@ -220,21 +220,15 @@ del _ComponentCollection
# The ID function # The ID function
ID = _xpcom.IID ID = _xpcom.IID
# A helper to cleanup our namespace as xpcom shuts down. def _on_shutdown():
class _ShutdownObserver: global manager, registrar, classes, interfaces, interfaceInfoManager, serviceManager, _constants_by_iid_map
_com_interfaces_ = interfaces.nsIObserver manager = registrar = classes = interfaces = interfaceInfoManager = serviceManager = _constants_by_iid_map = None
def observe(self, service, topic, extra): # for historical reasons we call these manually.
global manager, registrar, classes, interfaces, interfaceInfoManager, _shutdownObserver, serviceManager, _constants_by_iid_map xpcom.client._shutdown()
manager = registrar = classes = interfaces = interfaceInfoManager = _shutdownObserver = serviceManager = _constants_by_iid_map = None xpcom.server._shutdown()
xpcom.client._shutdown()
xpcom.server._shutdown()
svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/observer-service;1", interfaces.nsIObserverService) # import xpcom.shutdown late as it depends on us!
# Observers will be QI'd for a weak-reference, so we must keep the import shutdown
# observer alive ourself, and must keep the COM object alive, shutdown.register(_on_shutdown)
# _not_ just the Python instance!!!
_shutdownObserver = xpcom.server.WrapObject(_ShutdownObserver(), interfaces.nsIObserver) del _on_shutdown, shutdown
# Say we want a weak ref due to an assertion failing. If this is fixed, we can pass 0,
# and remove the lifetime hacks above! See http://bugzilla.mozilla.org/show_bug.cgi?id=99163
svc.addObserver(_shutdownObserver, "xpcom-shutdown", 1)
del svc, _ShutdownObserver

Просмотреть файл

@ -72,16 +72,13 @@ def UnwrapObject(ob):
ret = tracer_unwrap(ret) ret = tracer_unwrap(ret)
return ret return ret
# Create the main module for the Python loader. # Create the (Python implemented) module for the Python loader. This
# This is a once only init process, and the returned object # Python loader will then (indirectly) create other modules for any found
# if used to load all other Python components. # .py file components
# This means that we keep all factories, modules etc implemented in
# Python!
def NS_GetModule( serviceManager, nsIFile ): def NS_GetModule( serviceManager, nsIFile ):
import loader import loader, module
iid = _xpcom.IID_nsIModule iid = _xpcom.IID_nsIModule
return WrapObject(loader.MakePythonComponentLoaderModule(serviceManager, nsIFile), iid, bWrapClient = 0) return WrapObject(module.Module([loader.ModuleLoader]), iid, bWrapClient = 0)
def _shutdown(): def _shutdown():
from policy import _shutdown from policy import _shutdown

Просмотреть файл

@ -37,18 +37,11 @@
import xpcom import xpcom
from xpcom import components from xpcom import components
import xpcom.shutdown
import module import module
import glob, os, types import os, types
import traceback
from xpcom.client import Component
# Until we get interface constants.
When_Startup = 0
When_Component = 1
When_Timer = 2
def _has_good_attr(object, attr): def _has_good_attr(object, attr):
# Actually allows "None" to be specified to disable inherited attributes. # Actually allows "None" to be specified to disable inherited attributes.
@ -66,26 +59,37 @@ def FindCOMComponents(py_module):
return comps return comps
def register_self(klass, compMgr, location, registryLocation, componentType): def register_self(klass, compMgr, location, registryLocation, componentType):
pcl = PythonComponentLoader pcl = ModuleLoader
from xpcom import _xpcom from xpcom import _xpcom
svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/categorymanager;1", components.interfaces.nsICategoryManager) svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/categorymanager;1", components.interfaces.nsICategoryManager)
svc.addCategoryEntry("component-loader", pcl._reg_component_type_, pcl._reg_contractid_, 1, 1) # The category 'module-loader' is special - the component manager uses it
# to create the nsIModuleLoader for a given component type.
svc.addCategoryEntry("module-loader", pcl._reg_component_type_, pcl._reg_contractid_, 1, 1)
class PythonComponentLoader: # The Python module loader. Called by the component manager when it finds
_com_interfaces_ = components.interfaces.nsIComponentLoader # a component of type self._reg_component_type_. Responsible for returning
_reg_clsid_ = "{63B68B1E-3E62-45f0-98E3-5E0B5797970C}" # Never copy these! # an nsIModule for the file.
_reg_contractid_ = "moz.pyloader.1" class ModuleLoader:
_reg_desc_ = "Python component loader" _com_interfaces_ = components.interfaces.nsIModuleLoader
_reg_clsid_ = "{945BFDA9-0226-485e-8AE3-9A2F68F6116A}" # Never copy these!
_reg_contractid_ = "@mozilla.org/module-loader/python;1"
_reg_desc_ = "Python module loader"
# Optional function which performs additional special registration # Optional function which performs additional special registration
# Appears that no special unregistration is needed for ComponentLoaders, hence no unregister function. # Appears that no special unregistration is needed for ModuleLoaders, hence no unregister function.
_reg_registrar_ = (register_self,None) _reg_registrar_ = (register_self,None)
# Custom attributes for ComponentLoader registration. # Custom attributes for ModuleLoader registration.
_reg_component_type_ = "script/python" _reg_component_type_ = "application/x-python"
def __init__(self): def __init__(self):
self.com_modules = {} # Keyed by module's FQN as obtained from nsIFile.path self.com_modules = {} # Keyed by module's FQN as obtained from nsIFile.path
self.moduleFactory = module.Module self.moduleFactory = module.Module
self.num_modules_this_register = 0 xpcom.shutdown.register(self._on_shutdown)
def _on_shutdown(self):
self.com_modules.clear()
def loadModule(self, aFile):
return self._getCOMModuleForLocation(aFile)
def _getCOMModuleForLocation(self, componentFile): def _getCOMModuleForLocation(self, componentFile):
fqn = componentFile.path fqn = componentFile.path
@ -98,7 +102,7 @@ class PythonComponentLoader:
module_name_in_sys = "component:%s" % (base_name,) module_name_in_sys = "component:%s" % (base_name,)
stuff = loader.find_module(base_name, [componentFile.parent.path]) stuff = loader.find_module(base_name, [componentFile.parent.path])
assert stuff is not None, "Couldnt find the module '%s'" % (base_name,) assert stuff is not None, "Couldn't find the module '%s'" % (base_name,)
py_mod = loader.load_module( module_name_in_sys, stuff ) py_mod = loader.load_module( module_name_in_sys, stuff )
# Make and remember the COM module. # Make and remember the COM module.
@ -107,119 +111,3 @@ class PythonComponentLoader:
self.com_modules[fqn] = mod self.com_modules[fqn] = mod
return mod return mod
def getFactory(self, clsid, location, type):
# return the factory
assert type == self._reg_component_type_, "Being asked to create an object not of my type:%s" % (type,)
# FIXME: how to do this without obsolete component manager?
cmo = components.manager.queryInterface(components.interfaces.nsIComponentManagerObsolete)
file_interface = cmo.specForRegistryLocation(location)
# delegate to the module.
m = self._getCOMModuleForLocation(file_interface)
return m.getClassObject(components.manager, clsid, components.interfaces.nsIFactory)
def init(self, comp_mgr, registry):
# void
self.comp_mgr = comp_mgr
if xpcom.verbose:
print "Python component loader init() called"
# Called when a component of the appropriate type is registered,
# to give the component loader an opportunity to do things like
# annotate the registry and such.
def onRegister (self, clsid, type, className, proId, location, replace, persist):
if xpcom.verbose:
print "Python component loader - onRegister() called"
def autoRegisterComponents (self, when, directory):
directory_path = directory.path
self.num_modules_this_register = 0
if xpcom.verbose:
print "Auto-registering all Python components in", directory_path
# ToDo - work out the right thing here
# eg - do we recurse?
# - do we support packages?
entries = directory.directoryEntries
while entries.HasMoreElements():
entry = entries.GetNext(components.interfaces.nsIFile)
if os.path.splitext(entry.path)[1]==".py":
try:
self.autoRegisterComponent(when, entry)
# Handle some common user errors
except xpcom.COMException, details:
from xpcom import nsError
# If the interface name does not exist, suppress the traceback
if details.errno==nsError.NS_ERROR_NO_INTERFACE:
print "** Registration of '%s' failed\n %s" % (entry.leafName,details.message,)
else:
print "** Registration of '%s' failed!" % (entry.leafName,)
traceback.print_exc()
except SyntaxError, details:
# Syntax error in source file - no useful traceback here either.
print "** Registration of '%s' failed!" % (entry.leafName,)
traceback.print_exception(SyntaxError, details, None)
except:
# All other exceptions get the full traceback.
print "** Registration of '%s' failed!" % (entry.leafName,)
traceback.print_exc()
def autoRegisterComponent (self, when, componentFile):
# bool return
# Check if we actually need to do anything
modtime = componentFile.lastModifiedTime
loader_mgr = components.manager.queryInterface(components.interfaces.nsIComponentLoaderManager)
if not loader_mgr.hasFileChanged(componentFile, None, modtime):
return 1
if self.num_modules_this_register == 0:
# New components may have just installed new Python
# modules into the main python directory (including new .pth files)
# So we ask Python to re-process our site directory.
# Note that the pyloader does the equivalent when loading.
try:
from xpcom import _xpcom
import site
NS_XPCOM_CURRENT_PROCESS_DIR="XCurProcD"
dirname = _xpcom.GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR)
dirname.append("python")
site.addsitedir(dirname.path)
except:
print "PyXPCOM loader failed to process site directory before component registration"
traceback.print_exc()
self.num_modules_this_register += 1
# auto-register via the module.
m = self._getCOMModuleForLocation(componentFile)
m.registerSelf(components.manager, componentFile, None, self._reg_component_type_)
loader_mgr = components.manager.queryInterface(components.interfaces.nsIComponentLoaderManager)
loader_mgr.saveFileInfo(componentFile, None, modtime)
return 1
def autoUnregisterComponent (self, when, componentFile):
# bool return
# auto-unregister via the module.
m = self._getCOMModuleForLocation(componentFile)
loader_mgr = components.manager.queryInterface(components.interfaces.nsIComponentLoaderManager)
try:
m.unregisterSelf(components.manager, componentFile)
finally:
loader_mgr.removeFileInfo(componentFile, None)
return 1
def registerDeferredComponents (self, when):
# bool return
if xpcom.verbose:
print "Python component loader - registerDeferred() called"
return 0 # no more to register
def unloadAll (self, when):
if xpcom.verbose:
print "Python component loader being asked to unload all components!"
self.comp_mgr = None
self.com_modules = {}
def MakePythonComponentLoaderModule(serviceManager, nsIFile):
import module
return module.Module( [PythonComponentLoader] )

Просмотреть файл

@ -100,9 +100,8 @@ class Module:
if ok: if ok:
print "Successfully unregistered", klass.__name__ print "Successfully unregistered", klass.__name__
else: else:
print "Unregistration of", klass.__name__, "failed. (probably just not already registered)" print "Unregistration of", klass.__name__, "failed (not previously registered?)"
def canUnload(self, compMgr): def canUnload(self, compMgr):
# single bool result # single bool result
return 0 # we can never unload! return 0 # we can never unload!

Просмотреть файл

@ -140,7 +140,10 @@ class DefaultPolicy:
self._iid_ = iid self._iid_ = iid
if ni is None: if ni is None:
raise ValueError, "The object '%r' can not be used as a COM object" % (instance,) raise ValueError, "The object '%r' can not be used as a COM object" % (instance,)
# This is really only a check for the user # This is really only a check for the user - the same thing is
# done by the framework.
# XXXmarkh - this should probably die now we have better error
# reporting in the framework!
if __debug__: if __debug__:
if iid != IID_nsISupports and iid not in ni: if iid != IID_nsISupports and iid not in ni:
# The object may delegate QI. # The object may delegate QI.

Просмотреть файл

@ -0,0 +1,74 @@
# Utilities for registering functions to be called at xpcom shutdown.
#
# Pass xpcom.shutdown.register a function (and optionally args) that should
# be called as xpcom shutsdown. Relies on xpcom itself sending the
# standard shutdown notification.
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Python XPCOM language bindings.
#
# The Initial Developer of the Original Code is Mark Hammond.
# Portions created by the Initial Developer are Copyright (C) 2000
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
#
import xpcom.server
from xpcom import _xpcom
from xpcom.components import interfaces
import logging
_handlers = []
class _ShutdownObserver:
_com_interfaces_ = interfaces.nsIObserver
def observe(self, service, topic, extra):
logger = logging.getLogger('xpcom')
while _handlers:
func, args, kw = _handlers.pop()
try:
logger.debug("Calling shutdown handler '%s'(*%s, **%s)",
func, args, kw)
func(*args, **kw)
except:
logger.exception("Shutdown handler '%s' failed", func)
def register(func, *args, **kw):
_handlers.append( (func, args, kw) )
# Register
svc = _xpcom.GetServiceManager().getServiceByContractID(
"@mozilla.org/observer-service;1",
interfaces.nsIObserverService)
svc.addObserver(_ShutdownObserver(), "xpcom-shutdown", 0)
del svc, _ShutdownObserver

Просмотреть файл

@ -68,7 +68,6 @@ CPPSRCS= \
PyGWeakReference.cpp \ PyGWeakReference.cpp \
PyIClassInfo.cpp \ PyIClassInfo.cpp \
PyIComponentManager.cpp \ PyIComponentManager.cpp \
PyIComponentManagerObsolete.cpp \
PyIInputStream.cpp \ PyIInputStream.cpp \
PyIEnumerator.cpp \ PyIEnumerator.cpp \
PyIID.cpp \ PyIID.cpp \

Просмотреть файл

@ -48,7 +48,6 @@
#include "PyXPCOM_std.h" #include "PyXPCOM_std.h"
#include <nsIModule.h> #include <nsIModule.h>
#include <nsIComponentLoader.h>
#include <nsIInputStream.h> #include <nsIInputStream.h>
static PRInt32 cGateways = 0; static PRInt32 cGateways = 0;
@ -58,7 +57,6 @@ PRInt32 _PyXPCOM_GetGatewayCount(void)
} }
extern PyG_Base *MakePyG_nsIModule(PyObject *); extern PyG_Base *MakePyG_nsIModule(PyObject *);
extern PyG_Base *MakePyG_nsIComponentLoader(PyObject *instance);
extern PyG_Base *MakePyG_nsIInputStream(PyObject *instance); extern PyG_Base *MakePyG_nsIInputStream(PyObject *instance);
static char *PyXPCOM_szDefaultGatewayAttributeName = "_com_instance_default_gateway_"; static char *PyXPCOM_szDefaultGatewayAttributeName = "_com_instance_default_gateway_";
@ -77,8 +75,6 @@ PyG_Base::CreateNew(PyObject *pPyInstance, const nsIID &iid, void **ppResult)
// Hack for few extra gateways we support. // Hack for few extra gateways we support.
if (iid.Equals(NS_GET_IID(nsIModule))) if (iid.Equals(NS_GET_IID(nsIModule)))
ret = MakePyG_nsIModule(pPyInstance); ret = MakePyG_nsIModule(pPyInstance);
else if (iid.Equals(NS_GET_IID(nsIComponentLoader)))
ret = MakePyG_nsIComponentLoader(pPyInstance);
else if (iid.Equals(NS_GET_IID(nsIInputStream))) else if (iid.Equals(NS_GET_IID(nsIInputStream)))
ret = MakePyG_nsIInputStream(pPyInstance); ret = MakePyG_nsIInputStream(pPyInstance);
else else

Просмотреть файл

@ -53,7 +53,7 @@
#include "PyXPCOM_std.h" #include "PyXPCOM_std.h"
#include <nsIModule.h> #include <nsIModule.h>
#include <nsIComponentLoader.h> #include <nsIFile.h>
class PyG_nsIModule : public PyG_Base, public nsIModule class PyG_nsIModule : public PyG_Base, public nsIModule
{ {
@ -156,142 +156,3 @@ PyG_nsIModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
Py_XDECREF(ret); Py_XDECREF(ret);
return nr; return nr;
} }
///////////////////////////////////////////////////////////////////////////////////
class PyG_nsIComponentLoader : public PyG_Base, public nsIComponentLoader
{
public:
PyG_nsIComponentLoader(PyObject *instance) : PyG_Base(instance, NS_GET_IID(nsIComponentLoader)) {;}
PYGATEWAY_BASE_SUPPORT(nsIComponentLoader, PyG_Base);
NS_DECL_NSICOMPONENTLOADER
};
PyG_Base *MakePyG_nsIComponentLoader(PyObject *instance)
{
return new PyG_nsIComponentLoader(instance);
}
/* nsIFactory getFactory (in nsIIDRef aCID, in string aLocation, in string aType); */
NS_IMETHODIMP PyG_nsIComponentLoader::GetFactory(const nsIID & aCID, const char *aLocation, const char *aType, nsIFactory **_retval)
{
CEnterLeavePython _celp;
const char *methodName = "getFactory";
PyObject *iid = Py_nsIID::PyObjectFromIID(aCID);
PyObject *ret = NULL;
nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "Ozz",
iid,
aLocation,
aType);
Py_XDECREF(iid);
if (NS_SUCCEEDED(nr)) {
Py_nsISupports::InterfaceFromPyObject(ret, NS_GET_IID(nsIFactory), (nsISupports **)_retval, PR_FALSE);
if (PyErr_Occurred())
nr = HandleNativeGatewayError(methodName);
}
Py_XDECREF(ret);
return nr;
}
/* void init (in nsIComponentManager aCompMgr, in nsISupports aRegistry); */
NS_IMETHODIMP PyG_nsIComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aRegistry)
{
CEnterLeavePython _celp;
const char *methodName = "init";
PyObject *c = Py_nsISupports::PyObjectFromInterface(aCompMgr, NS_GET_IID(nsIComponentManager), PR_TRUE);
PyObject *r = Py_nsISupports::PyObjectFromInterface(aRegistry, NS_GET_IID(nsISupports), PR_TRUE);
nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "OO", c, r);
Py_XDECREF(c);
Py_XDECREF(r);
return nr;
}
/* void onRegister (in nsIIDRef aCID, in string aType, in string aClassName, in string aContractID, in string aLocation, in boolean aReplace, in boolean aPersist); */
NS_IMETHODIMP PyG_nsIComponentLoader::OnRegister(const nsIID & aCID, const char *aType, const char *aClassName, const char *aContractID, const char *aLocation, PRBool aReplace, PRBool aPersist)
{
CEnterLeavePython _celp;
const char *methodName = "onRegister";
PyObject *iid = Py_nsIID::PyObjectFromIID(aCID);
nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "Ossssii",
iid,
aType,
aClassName,
aContractID,
aLocation,
aReplace,
aPersist);
Py_XDECREF(iid);
return nr;
}
/* void autoRegisterComponents (in long aWhen, in nsIFile aDirectory); */
NS_IMETHODIMP PyG_nsIComponentLoader::AutoRegisterComponents(PRInt32 aWhen, nsIFile *aDirectory)
{
CEnterLeavePython _celp;
const char *methodName = "autoRegisterComponents";
PyObject *c = Py_nsISupports::PyObjectFromInterface(aDirectory, NS_GET_IID(nsIFile), PR_TRUE);
nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "iO", aWhen, c);
Py_XDECREF(c);
return nr;
}
/* boolean autoRegisterComponent (in long aWhen, in nsIFile aComponent); */
NS_IMETHODIMP PyG_nsIComponentLoader::AutoRegisterComponent(PRInt32 aWhen, nsIFile *aComponent, PRBool *_retval)
{
CEnterLeavePython _celp;
const char *methodName = "autoRegisterComponent";
PyObject *ret = NULL;
PyObject *c = Py_nsISupports::PyObjectFromInterface(aComponent, NS_GET_IID(nsIFile), PR_TRUE);
nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "iO", aWhen, c);
Py_XDECREF(c);
if (NS_SUCCEEDED(nr)) {
*_retval = PyInt_AsLong(ret);
if (PyErr_Occurred())
nr = HandleNativeGatewayError(methodName);
}
Py_XDECREF(ret);
return nr;
}
/* boolean autoUnregisterComponent (in long aWhen, in nsIFile aComponent); */
NS_IMETHODIMP PyG_nsIComponentLoader::AutoUnregisterComponent(PRInt32 aWhen, nsIFile *aComponent, PRBool *_retval)
{
CEnterLeavePython _celp;
const char *methodName = "autoUnregisterComponent";
PyObject *ret = NULL;
PyObject *c = Py_nsISupports::PyObjectFromInterface(aComponent, NS_GET_IID(nsIFile), PR_TRUE);
nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "iO", aWhen, c);
Py_XDECREF(c);
if (NS_SUCCEEDED(nr)) {
*_retval = PyInt_AsLong(ret);
if (PyErr_Occurred())
nr = HandleNativeGatewayError(methodName);
}
Py_XDECREF(ret);
return nr;
}
/* boolean registerDeferredComponents (in long aWhen); */
NS_IMETHODIMP PyG_nsIComponentLoader::RegisterDeferredComponents(PRInt32 aWhen, PRBool *_retval)
{
CEnterLeavePython _celp;
const char *methodName = "registerDeferredComponents";
PyObject *ret = NULL;
nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "i", aWhen);
if (NS_SUCCEEDED(nr)) {
*_retval = PyInt_AsLong(ret);
if (PyErr_Occurred())
nr = HandleNativeGatewayError(methodName);
}
Py_XDECREF(ret);
return nr;
}
/* void unloadAll (in long aWhen); */
NS_IMETHODIMP PyG_nsIComponentLoader::UnloadAll(PRInt32 aWhen)
{
CEnterLeavePython _celp;
const char *methodName = "unloadAll";
return InvokeNativeViaPolicy(methodName, NULL, "i", aWhen);
}

Просмотреть файл

Просмотреть файл

@ -102,7 +102,6 @@ PyXPCOM_TypeObject::Py_setattr(PyObject *op, char *name, PyObject *v)
/*static*/int /*static*/int
PyXPCOM_TypeObject::Py_cmp(PyObject *self, PyObject *other) PyXPCOM_TypeObject::Py_cmp(PyObject *self, PyObject *other)
{ {
// @comm NOTE: Copied from COM - have not confirmed these rules are true for XPCOM
// @comm As per the XPCOM rules for object identity, both objects are queried for nsISupports, and these values compared. // @comm As per the XPCOM rules for object identity, both objects are queried for nsISupports, and these values compared.
// The only meaningful test is for equality - the result of other comparisons is undefined // The only meaningful test is for equality - the result of other comparisons is undefined
// (ie, determined by the object's relative addresses in memory. // (ie, determined by the object's relative addresses in memory.

Просмотреть файл

@ -49,7 +49,6 @@
#undef HAVE_LONG_LONG #undef HAVE_LONG_LONG
#endif #endif
#include "nsIComponentLoader.h"
#include "nsISupports.h" #include "nsISupports.h"
#include "nsIModule.h" #include "nsIModule.h"
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"

Просмотреть файл

@ -1,638 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Python XPCOM language bindings.
*
* The Initial Developer of the Original Code is
* ActiveState Tool Corp.
* Portions created by the Initial Developer are Copyright (C) 2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Hammond <mhammond@skippinet.com.au> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
//
// This code is part of the XPCOM extensions for Python.
//
// Written May 2000 by Mark Hammond.
//
// Based heavily on the Python COM support, which is
// (c) Mark Hammond and Greg Stein.
//
// (c) 2000, ActiveState corp.
#include "PyXPCOM_std.h"
#include "nsIThread.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIModule.h"
#include "nsIFile.h"
#include "nsILocalFile.h"
#include "nsIComponentRegistrar.h"
#include "nsIComponentManagerObsolete.h"
#ifdef XP_WIN
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "windows.h"
#endif
#include "nsIEventQueue.h"
#include "nsIProxyObjectManager.h"
PYXPCOM_EXPORT PyObject *PyXPCOM_Error = NULL;
extern PRInt32 _PyXPCOM_GetGatewayCount(void);
extern PRInt32 _PyXPCOM_GetInterfaceCount(void);
extern void AddDefaultGateway(PyObject *instance, nsISupports *gateway);
#define LOADER_LINKS_WITH_PYTHON
#ifndef PYXPCOM_USE_PYGILSTATE
extern void PyXPCOM_InterpreterState_Ensure();
#endif
PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
PyXPCOM_INTERFACE_DEFINE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
PyXPCOM_INTERFACE_DEFINE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
PyXPCOM_INTERFACE_DEFINE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
PyXPCOM_INTERFACE_DEFINE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
PyXPCOM_INTERFACE_DEFINE(Py_nsIVariant, nsIVariant, PyMethods_IVariant)
// deprecated, but retained for backward compatibility:
PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete)
////////////////////////////////////////////////////////////
// This is the main entry point called by the Python component
// loader.
extern "C" NS_EXPORT nsresult PyXPCOM_NSGetModule(nsIComponentManager *servMgr,
nsIFile* location,
nsIModule** result)
{
NS_PRECONDITION(result!=NULL, "null result pointer in PyXPCOM_NSGetModule!");
NS_PRECONDITION(location!=NULL, "null nsIFile pointer in PyXPCOM_NSGetModule!");
NS_PRECONDITION(servMgr!=NULL, "null servMgr pointer in PyXPCOM_NSGetModule!");
#ifndef LOADER_LINKS_WITH_PYTHON
if (!Py_IsInitialized()) {
Py_Initialize();
if (!Py_IsInitialized()) {
PyXPCOM_LogError("Python initialization failed!\n");
return NS_ERROR_FAILURE;
}
PyEval_InitThreads();
#ifndef PYXPCOM_USE_PYGILSTATE
PyXPCOM_InterpreterState_Ensure();
#endif
PyEval_SaveThread();
}
#endif // LOADER_LINKS_WITH_PYTHON
CEnterLeavePython _celp;
PyObject *func = NULL;
PyObject *obServMgr = NULL;
PyObject *obLocation = NULL;
PyObject *wrap_ret = NULL;
PyObject *args = NULL;
PyObject *mod = PyImport_ImportModule("xpcom.server");
if (!mod) goto done;
func = PyObject_GetAttrString(mod, "NS_GetModule");
if (func==NULL) goto done;
obServMgr = Py_nsISupports::PyObjectFromInterface(servMgr, NS_GET_IID(nsIComponentManager), PR_TRUE);
if (obServMgr==NULL) goto done;
obLocation = Py_nsISupports::PyObjectFromInterface(location, NS_GET_IID(nsIFile), PR_TRUE);
if (obLocation==NULL) goto done;
args = Py_BuildValue("OO", obServMgr, obLocation);
if (args==NULL) goto done;
wrap_ret = PyEval_CallObject(func, args);
if (wrap_ret==NULL) goto done;
Py_nsISupports::InterfaceFromPyObject(wrap_ret, NS_GET_IID(nsIModule), (nsISupports **)result, PR_FALSE, PR_FALSE);
done:
nsresult nr = NS_OK;
if (PyErr_Occurred()) {
PyXPCOM_LogError("Obtaining the module object from Python failed.\n");
nr = PyXPCOM_SetCOMErrorFromPyException();
}
Py_XDECREF(func);
Py_XDECREF(obServMgr);
Py_XDECREF(obLocation);
Py_XDECREF(wrap_ret);
Py_XDECREF(mod);
Py_XDECREF(args);
return nr;
}
// "boot-strap" methods - interfaces we need to get the base
// interface support!
/* deprecated, included for backward compatibility */
static PyObject *
PyXPCOMMethod_NS_GetGlobalComponentManager(PyObject *self, PyObject *args)
{
if (PyErr_Warn(PyExc_DeprecationWarning, "Use GetComponentManager instead") < 0)
return NULL;
if (!PyArg_ParseTuple(args, ""))
return NULL;
nsIComponentManager* cm;
nsresult rv;
Py_BEGIN_ALLOW_THREADS;
rv = NS_GetComponentManager(&cm);
Py_END_ALLOW_THREADS;
if ( NS_FAILED(rv) )
return PyXPCOM_BuildPyException(rv);
nsCOMPtr<nsIComponentManagerObsolete> ocm(do_QueryInterface(cm, &rv));
if ( NS_FAILED(rv) )
return PyXPCOM_BuildPyException(rv);
return Py_nsISupports::PyObjectFromInterface(cm, NS_GET_IID(nsIComponentManagerObsolete), PR_FALSE, PR_FALSE);
}
static PyObject *
PyXPCOMMethod_GetComponentManager(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
nsIComponentManager* cm;
nsresult rv;
Py_BEGIN_ALLOW_THREADS;
rv = NS_GetComponentManager(&cm);
Py_END_ALLOW_THREADS;
if ( NS_FAILED(rv) )
return PyXPCOM_BuildPyException(rv);
return Py_nsISupports::PyObjectFromInterface(cm, NS_GET_IID(nsIComponentManager), PR_FALSE, PR_FALSE);
}
static PyObject *
PyXPCOMMethod_GetServiceManager(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
nsIServiceManager* sm;
nsresult rv;
Py_BEGIN_ALLOW_THREADS;
rv = NS_GetServiceManager(&sm);
Py_END_ALLOW_THREADS;
if ( NS_FAILED(rv) )
return PyXPCOM_BuildPyException(rv);
// Return a type based on the IID.
return Py_nsISupports::PyObjectFromInterface(sm, NS_GET_IID(nsIServiceManager), PR_FALSE);
}
/* deprecated, included for backward compatibility */
static PyObject *
PyXPCOMMethod_GetGlobalServiceManager(PyObject *self, PyObject *args)
{
if (PyErr_Warn(PyExc_DeprecationWarning, "Use GetServiceManager instead") < 0)
return NULL;
return PyXPCOMMethod_GetComponentManager(self, args);
}
static PyObject *
PyXPCOMMethod_XPTI_GetInterfaceInfoManager(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
return NULL;
nsCOMPtr<nsIInterfaceInfoManager> im(do_GetService(
NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
if ( im == nsnull )
return PyXPCOM_BuildPyException(NS_ERROR_FAILURE);
/* Return a type based on the IID (with no extra ref) */
// Can not auto-wrap the interface info manager as it is critical to
// building the support we need for autowrap.
return Py_nsISupports::PyObjectFromInterface(im, NS_GET_IID(nsIInterfaceInfoManager), PR_TRUE, PR_FALSE);
}
static PyObject *
PyXPCOMMethod_XPTC_InvokeByIndex(PyObject *self, PyObject *args)
{
PyObject *obIS, *obParams;
nsCOMPtr<nsISupports> pis;
int index;
// We no longer rely on PyErr_Occurred() for our error state,
// but keeping this assertion can't hurt - it should still always be true!
NS_WARN_IF_FALSE(!PyErr_Occurred(), "Should be no pending Python error!");
if (!PyArg_ParseTuple(args, "OiO", &obIS, &index, &obParams))
return NULL;
// Ack! We must ask for the "native" interface supported by
// the object, not specifically nsISupports, else we may not
// back the same pointer (eg, Python, following identity rules,
// will return the "original" gateway when QI'd for nsISupports)
if (!Py_nsISupports::InterfaceFromPyObject(
obIS,
Py_nsIID_NULL,
getter_AddRefs(pis),
PR_FALSE))
return NULL;
PyXPCOM_InterfaceVariantHelper arg_helper;
if (!arg_helper.Init(obParams))
return NULL;
if (!arg_helper.FillArray())
return NULL;
nsresult r;
Py_BEGIN_ALLOW_THREADS;
r = XPTC_InvokeByIndex(pis, index, arg_helper.m_num_array, arg_helper.m_var_array);
Py_END_ALLOW_THREADS;
if ( NS_FAILED(r) )
return PyXPCOM_BuildPyException(r);
return arg_helper.MakePythonResult();
}
static PyObject *
PyXPCOMMethod_WrapObject(PyObject *self, PyObject *args)
{
PyObject *ob, *obIID;
int bWrapClient = 1;
if (!PyArg_ParseTuple(args, "OO|i", &ob, &obIID, &bWrapClient))
return NULL;
nsIID iid;
if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
return NULL;
nsISupports *ret = NULL;
nsresult r = PyXPCOM_XPTStub::CreateNew(ob, iid, (void **)&ret);
if ( NS_FAILED(r) )
return PyXPCOM_BuildPyException(r);
// _ALL_ wrapped objects are associated with a weak-ref
// to their "main" instance.
AddDefaultGateway(ob, ret); // inject a weak reference to myself into the instance.
// Now wrap it in an interface.
return Py_nsISupports::PyObjectFromInterface(ret, iid, PR_FALSE, bWrapClient);
}
static PyObject *
PyXPCOMMethod_UnwrapObject(PyObject *self, PyObject *args)
{
PyObject *ob;
if (!PyArg_ParseTuple(args, "O", &ob))
return NULL;
nsISupports *uob = NULL;
nsIInternalPython *iob = NULL;
PyObject *ret = NULL;
if (!Py_nsISupports::InterfaceFromPyObject(ob,
NS_GET_IID(nsISupports),
&uob,
PR_FALSE))
goto done;
if (NS_FAILED(uob->QueryInterface(NS_GET_IID(nsIInternalPython), reinterpret_cast<void **>(&iob)))) {
PyErr_SetString(PyExc_ValueError, "This XPCOM object is not implemented by Python");
goto done;
}
ret = iob->UnwrapPythonObject();
done:
Py_BEGIN_ALLOW_THREADS;
NS_IF_RELEASE(uob);
NS_IF_RELEASE(iob);
Py_END_ALLOW_THREADS;
return ret;
}
// @pymethod int|pythoncom|_GetInterfaceCount|Retrieves the number of interface objects currently in existance
static PyObject *
PyXPCOMMethod_GetInterfaceCount(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":_GetInterfaceCount"))
return NULL;
return PyInt_FromLong(_PyXPCOM_GetInterfaceCount());
// @comm If is occasionally a good idea to call this function before your Python program
// terminates. If this function returns non-zero, then you still have PythonCOM objects
// alive in your program (possibly in global variables).
}
// @pymethod int|pythoncom|_GetGatewayCount|Retrieves the number of gateway objects currently in existance
static PyObject *
PyXPCOMMethod_GetGatewayCount(PyObject *self, PyObject *args)
{
// @comm This is the number of Python object that implement COM servers which
// are still alive (ie, serving a client). The only way to reduce this count
// is to have the process which uses these PythonCOM servers release its references.
if (!PyArg_ParseTuple(args, ":_GetGatewayCount"))
return NULL;
return PyInt_FromLong(_PyXPCOM_GetGatewayCount());
}
static PyObject *
PyXPCOMMethod_NS_ShutdownXPCOM(PyObject *self, PyObject *args)
{
// @comm This is the number of Python object that implement COM servers which
// are still alive (ie, serving a client). The only way to reduce this count
// is to have the process which uses these PythonCOM servers release its references.
if (!PyArg_ParseTuple(args, ":NS_ShutdownXPCOM"))
return NULL;
nsresult nr;
Py_BEGIN_ALLOW_THREADS;
nr = NS_ShutdownXPCOM(nsnull);
Py_END_ALLOW_THREADS;
// Don't raise an exception - as we are probably shutting down
// and don't really care - just return the status
return PyInt_FromLong(nr);
}
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
// A hack to work around their magic constants!
static PyObject *
PyXPCOMMethod_GetProxyForObject(PyObject *self, PyObject *args)
{
PyObject *obQueue, *obIID, *obOb;
int flags;
if (!PyArg_ParseTuple(args, "OOOi", &obQueue, &obIID, &obOb, &flags))
return NULL;
nsIID iid;
if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
return NULL;
nsCOMPtr<nsISupports> pob;
if (!Py_nsISupports::InterfaceFromPyObject(obOb, iid, getter_AddRefs(pob), PR_FALSE))
return NULL;
nsIEventQueue *pQueue = NULL;
nsIEventQueue *pQueueRelease = NULL;
if (PyInt_Check(obQueue)) {
pQueue = (nsIEventQueue *)PyInt_AsLong(obQueue);
} else {
if (!Py_nsISupports::InterfaceFromPyObject(obQueue, NS_GET_IID(nsIEventQueue), (nsISupports **)&pQueue, PR_TRUE))
return NULL;
pQueueRelease = pQueue;
}
nsresult rv_proxy;
nsISupports *presult = nsnull;
Py_BEGIN_ALLOW_THREADS;
nsCOMPtr<nsIProxyObjectManager> proxyMgr =
do_GetService(kProxyObjectManagerCID, &rv_proxy);
if ( NS_SUCCEEDED(rv_proxy) ) {
rv_proxy = proxyMgr->GetProxyForObject(pQueue,
iid,
pob,
flags,
(void **)&presult);
}
if (pQueueRelease)
pQueueRelease->Release();
Py_END_ALLOW_THREADS;
PyObject *result;
if (NS_SUCCEEDED(rv_proxy) ) {
result = Py_nsISupports::PyObjectFromInterface(presult, iid, PR_FALSE);
} else {
result = PyXPCOM_BuildPyException(rv_proxy);
}
return result;
}
PyObject *PyGetSpecialDirectory(PyObject *self, PyObject *args)
{
char *dirname;
if (!PyArg_ParseTuple(args, "s:GetSpecialDirectory", &dirname))
return NULL;
nsIFile *file = NULL;
nsresult r = NS_GetSpecialDirectory(dirname, &file);
if ( NS_FAILED(r) )
return PyXPCOM_BuildPyException(r);
// returned object swallows our reference.
return Py_nsISupports::PyObjectFromInterface(file, NS_GET_IID(nsIFile), PR_FALSE);
}
PyObject *AllocateBuffer(PyObject *self, PyObject *args)
{
int bufSize;
if (!PyArg_ParseTuple(args, "i", &bufSize))
return NULL;
return PyBuffer_New(bufSize);
}
PyObject *LogWarning(PyObject *self, PyObject *args)
{
char *msg;
if (!PyArg_ParseTuple(args, "s", &msg))
return NULL;
PyXPCOM_LogWarning("%s", msg);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *LogError(PyObject *self, PyObject *args)
{
char *msg;
if (!PyArg_ParseTuple(args, "s", &msg))
return NULL;
PyXPCOM_LogError("%s", msg);
Py_INCREF(Py_None);
return Py_None;
}
extern PyObject *PyXPCOMMethod_IID(PyObject *self, PyObject *args);
static struct PyMethodDef xpcom_methods[]=
{
{"GetComponentManager", PyXPCOMMethod_GetComponentManager, 1},
{"NS_GetGlobalComponentManager", PyXPCOMMethod_NS_GetGlobalComponentManager, 1}, // deprecated
{"XPTI_GetInterfaceInfoManager", PyXPCOMMethod_XPTI_GetInterfaceInfoManager, 1},
{"XPTC_InvokeByIndex", PyXPCOMMethod_XPTC_InvokeByIndex, 1},
{"GetServiceManager", PyXPCOMMethod_GetServiceManager, 1},
{"GetGlobalServiceManager", PyXPCOMMethod_GetGlobalServiceManager, 1}, // deprecated
{"IID", PyXPCOMMethod_IID, 1}, // IID is wrong - deprecated - not just IID, but CID, etc.
{"ID", PyXPCOMMethod_IID, 1}, // This is the official name.
{"NS_ShutdownXPCOM", PyXPCOMMethod_NS_ShutdownXPCOM, 1},
{"WrapObject", PyXPCOMMethod_WrapObject, 1},
{"UnwrapObject", PyXPCOMMethod_UnwrapObject, 1},
{"_GetInterfaceCount", PyXPCOMMethod_GetInterfaceCount, 1},
{"_GetGatewayCount", PyXPCOMMethod_GetGatewayCount, 1},
{"getProxyForObject", PyXPCOMMethod_GetProxyForObject, 1},
{"GetProxyForObject", PyXPCOMMethod_GetProxyForObject, 1},
{"GetSpecialDirectory", PyGetSpecialDirectory, 1},
{"AllocateBuffer", AllocateBuffer, 1},
{"LogWarning", LogWarning, 1},
{"LogError", LogError, 1},
{ NULL }
};
////////////////////////////////////////////////////////////
// Other helpers/global functions.
//
PRBool PyXPCOM_Globals_Ensure()
{
PRBool rc = PR_TRUE;
#ifndef PYXPCOM_USE_PYGILSTATE
PyXPCOM_InterpreterState_Ensure();
#endif
// The exception object - we load it from .py code!
if (PyXPCOM_Error == NULL) {
rc = PR_FALSE;
PyObject *mod = NULL;
mod = PyImport_ImportModule("xpcom");
if (mod!=NULL) {
PyXPCOM_Error = PyObject_GetAttrString(mod, "Exception");
Py_DECREF(mod);
}
rc = (PyXPCOM_Error != NULL);
}
if (!rc)
return rc;
static PRBool bHaveInitXPCOM = PR_FALSE;
if (!bHaveInitXPCOM) {
nsCOMPtr<nsIThread> thread_check;
// xpcom appears to assert if already initialized
// Is there an official way to determine this?
if (NS_FAILED(nsIThread::GetMainThread(getter_AddRefs(thread_check)))) {
// not already initialized.
#ifdef XP_WIN
// On Windows, we need to locate the Mozilla bin
// directory. This by using locating a Moz DLL we depend
// on, and assume it lives in that bin dir. Different
// moz build types (eg, xulrunner, suite) package
// XPCOM itself differently - but all appear to require
// nspr4.dll - so this is what we use.
char landmark[MAX_PATH+1];
HMODULE hmod = GetModuleHandle("nspr4.dll");
if (hmod==NULL) {
PyErr_SetString(PyExc_RuntimeError, "We dont appear to be linked against nspr4.dll.");
return PR_FALSE;
}
GetModuleFileName(hmod, landmark, sizeof(landmark)/sizeof(landmark[0]));
char *end = landmark + (strlen(landmark)-1);
while (end > landmark && *end != '\\')
end--;
if (end > landmark) *end = '\0';
nsCOMPtr<nsILocalFile> ns_bin_dir;
NS_ConvertASCIItoUCS2 strLandmark(landmark);
NS_NewLocalFile(strLandmark, PR_FALSE, getter_AddRefs(ns_bin_dir));
nsresult rv = NS_InitXPCOM2(nsnull, ns_bin_dir, nsnull);
#else
// Elsewhere, Mozilla can find it itself (we hope!)
nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
#endif // XP_WIN
if (NS_FAILED(rv)) {
PyErr_SetString(PyExc_RuntimeError, "The XPCOM subsystem could not be initialized");
return PR_FALSE;
}
}
// Even if xpcom was already init, we want to flag it as init!
bHaveInitXPCOM = PR_TRUE;
}
return rc;
}
#define REGISTER_IID(t) { \
PyObject *iid_ob = Py_nsIID::PyObjectFromIID(NS_GET_IID(t)); \
PyDict_SetItemString(dict, "IID_"#t, iid_ob); \
Py_DECREF(iid_ob); \
}
#define REGISTER_INT(val) { \
PyObject *ob = PyInt_FromLong(val); \
PyDict_SetItemString(dict, #val, ob); \
Py_DECREF(ob); \
}
////////////////////////////////////////////////////////////
// The module init code.
//
extern "C" NS_EXPORT
void
init_xpcom() {
PyObject *oModule;
// ensure the framework has valid state to work with.
if (!PyXPCOM_Globals_Ensure())
return;
// Must force Python to start using thread locks
PyEval_InitThreads();
// Create the module and add the functions
oModule = Py_InitModule("_xpcom", xpcom_methods);
PyObject *dict = PyModule_GetDict(oModule);
PyObject *pycom_Error = PyXPCOM_Error;
if (pycom_Error == NULL || PyDict_SetItemString(dict, "error", pycom_Error) != 0)
{
PyErr_SetString(PyExc_MemoryError, "can't define error");
return;
}
PyDict_SetItemString(dict, "IIDType", (PyObject *)&Py_nsIID::type);
// register our entry point.
PyObject *obFuncPtr = PyLong_FromVoidPtr((void *)&PyXPCOM_NSGetModule);
if (obFuncPtr)
PyDict_SetItemString(dict,
"_NSGetModule_FuncPtr",
obFuncPtr);
Py_XDECREF(obFuncPtr);
REGISTER_IID(nsISupports);
REGISTER_IID(nsISupportsCString);
REGISTER_IID(nsIModule);
REGISTER_IID(nsIFactory);
REGISTER_IID(nsIWeakReference);
REGISTER_IID(nsISupportsWeakReference);
REGISTER_IID(nsIClassInfo);
REGISTER_IID(nsIServiceManager);
REGISTER_IID(nsIComponentRegistrar);
// Register our custom interfaces.
Py_nsISupports::InitType();
Py_nsIComponentManager::InitType(dict);
Py_nsIInterfaceInfoManager::InitType(dict);
Py_nsIEnumerator::InitType(dict);
Py_nsISimpleEnumerator::InitType(dict);
Py_nsIInterfaceInfo::InitType(dict);
Py_nsIInputStream::InitType(dict);
Py_nsIClassInfo::InitType(dict);
Py_nsIVariant::InitType(dict);
// for backward compatibility:
Py_nsIComponentManagerObsolete::InitType(dict);
// We have special support for proxies - may as well add their constants!
REGISTER_INT(PROXY_SYNC);
REGISTER_INT(PROXY_ASYNC);
REGISTER_INT(PROXY_ALWAYS);
}