A number of changes moving towards dynamic linking support on Linux.

Not part of the build.
This commit is contained in:
markh%activestate.com 2001-04-14 13:41:35 +00:00
Родитель f3b47afd41
Коммит 1034ad92c9
4 изменённых файлов: 110 добавлений и 81 удалений

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

@ -37,70 +37,6 @@
#include <nsIModule.h>
#include <nsIComponentLoader.h>
#ifdef XP_WIN
// Can only assume dynamic loading on Windows.
#define LOADER_LINKS_WITH_PYTHON
#endif // XP_WIN
extern void PyXPCOM_InterpreterState_Ensure();
////////////////////////////////////////////////////////////
// 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();
PyXPCOM_InterpreterState_Ensure();
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;
}
class PyG_nsIModule : public PyG_Base, public nsIModule
{
public:

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

@ -34,16 +34,6 @@
// Main Mozilla cross-platform declarations.
#include "xp_core.h"
#ifdef _DEBUG
# ifndef DEBUG
# define DEBUG
# endif
# define DEVELOPER_DEBUG
# define NS_DEBUG
# define DEBUG_markh
#endif // DEBUG
#include <nsIAllocator.h>
#include <nsIWeakReference.h>
#include <nsXPIDLString.h>

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

@ -30,7 +30,10 @@
#include "nsIRegistry.h"
#include "nsISupports.h"
#include "nsIModule.h"
#include "nsDirectoryServiceDefs.h"
#include "nsILocalFile.h"
#include "nsXPIDLString.h"
#include <nsFileStream.h> // For console logging.
#ifdef HAVE_LONG_LONG
@ -78,6 +81,36 @@ pfnPyXPCOM_NSGetModule pfnEntryPoint = nsnull;
static void LogError(const char *fmt, ...);
static void LogDebug(const char *fmt, ...);
#ifdef LOADER_LINKS_WITH_PYTHON
// Ensure that any paths guaranteed by this package exist on sys.path
// Only called once as we are first loaded into the process.
void AddStandardPaths()
{
// Put {bin}\Python on the path if it exists.
nsCOMPtr<nsIFile> aFile;
nsCOMPtr<nsILocalFile> aLocalFile;
NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(aFile));
if (!aFile) {
LogError("The Python XPCOM loader could not locate the 'bin' directory\n");
return;
}
aFile->Append("python");
nsXPIDLCString pathBuf;
aFile->GetPath(getter_Copies(pathBuf));
PyObject *obPath = PySys_GetObject("path");
if (!obPath) {
LogError("The Python XPCOM loader could not get the Python sys.path variable\n");
return;
}
LogDebug("The Python XPCOM loader is adding '%s' to sys.path\n", (const char *)pathBuf);
// DebugBreak();
PyObject *newStr = PyString_FromString(pathBuf);
PyList_Insert(obPath, 0, newStr);
Py_XDECREF(newStr);
}
#endif
extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
nsIFile* location,
@ -91,14 +124,12 @@ extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
#ifdef LOADER_LINKS_WITH_PYTHON
PRBool bDidInitPython = !Py_IsInitialized(); // well, I will next line, anyway :-)
if (bDidInitPython) {
// If Python was already initialized, we almost certainly
// do not have the thread-lock, so can not attempt to import anything
// We simply must assume/hope that Python already has our module loaded.
Py_Initialize();
if (!Py_IsInitialized()) {
LogError("Python initialization failed!\n");
return NS_ERROR_FAILURE;
}
AddStandardPaths();
PyObject *mod = PyImport_ImportModule("xpcom._xpcom");
if (mod==NULL) {
LogError("Could not import the Python XPCOM extension\n");
@ -224,14 +255,16 @@ static void LogWarning(const char *fmt, ...)
}
#ifdef DEBUG
void LogDebug(const char *fmt, ...)
static void LogDebug(const char *fmt, ...)
{
va_list marker;
va_start(marker, fmt);
VLogF("PyXPCOM Loader Debug: ", fmt, marker);
}
#else
#define LogDebug()
static void LogDebug(const char *fmt, ...)
{
}
#endif
#ifdef LOADER_LINKS_WITH_PYTHON

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

@ -50,6 +50,69 @@ extern PRInt32 _PyXPCOM_GetGatewayCount(void);
extern PRInt32 _PyXPCOM_GetInterfaceCount(void);
extern void AddDefaultGateway(PyObject *instance, nsISupports *gateway);
extern void PyXPCOM_InterpreterState_Ensure();
#ifdef XP_WIN
// Can only assume dynamic loading on Windows.
#define LOADER_LINKS_WITH_PYTHON
#endif // XP_WIN
////////////////////////////////////////////////////////////
// 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();
PyXPCOM_InterpreterState_Ensure();
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;
}
// Hrm - So we can't have templates, eh??
// preprocessor to the rescue, I guess.
@ -107,7 +170,6 @@ PyXPCOMMethod_NS_LocateSpecialSystemDirectory(PyObject *self, PyObject *args)
int typ;
if (!PyArg_ParseTuple(args, "i", &typ))
return NULL;
nsIFileSpec *spec = NULL;
nsSpecialSystemDirectory systemDir((nsSpecialSystemDirectory::SystemDirectories)typ);
return PyString_FromString(systemDir.GetNativePathCString());
}
@ -524,6 +586,14 @@ init_xpcom() {
}
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(nsISupportsString);
REGISTER_IID(nsIModule);