views:

48

answers:

0

I am running 64 bit ubuntu 10.10 in case there are know issues with this setup, basically i am embedding python inside a c application i managed to get this to work i can call functions from the original c program and the scripts run until i import gtk in the python script this causes the error below.

I am using the waf build system to build the c program, my knowledge of c is limited i am more a python programmer which is why i am attempting the embed python so i can write my plugins in python.

I get the feeling the error is todo with linking but i dont get why i can import gtk normally in python but not when its embeded ?

I can confirm the lib its looking for exists with the commands below. locate /usr/lib/libpyglib /usr/lib/libpyglib-2.0-python2.6.so.0 /usr/lib/libpyglib-2.0-python2.6.so.0.0.0

Any help or pointers would be appreciated, that might help me get this solved or better understand what is wrong.

Traceback (most recent call last):
  File "/usr/local/share/geany/plugins/gpykickstart.py", line 4, in
<module>
    import glib
  File "/usr/lib/pymodules/python2.6/gtk-2.0/glib/__init__.py", line 22,
in <module>
    from glib._glib import *
ImportError: /usr/lib/libpyglib-2.0-python2.6.so.0: undefined symbol:
PyExc_ImportError
Failed to load the "gpykickstart" module from the
"/usr/local/share/geany/plugins" directory.

This is the code i am trying to run in the embeded python interpreter, if i take out the import gtk option it works fine.

import sys
import pygtk
pygtk.require('2.0')
import gtk

Here is the c code i currently have i have tried to strip it down to a minimum to just load the python file and reproduce the error.

#include <Python.h>             /* For Python itself. This MUST come first. */
#include "geany.h"              /* for the GeanyApp data type */
#include "geanyplugin.h"        /* for the GeanyApp data type */
#include "plugindata.h"         /* this defines the plugin API */

#define PLUGIN_NAME _("Geany Python Bindings")

/* These items are set by Geany before plugin_init() is called. */
GeanyPlugin     *geany_plugin;
GeanyData       *geany_data;
GeanyFunctions  *geany_functions;

PyObject *pKickstartModule = NULL;

/* All plugins must set name, description, version and author. */
PLUGIN_VERSION_CHECK(GEANY_API_VERSION)
PLUGIN_SET_INFO(PLUGIN_NAME, _("Load a python plugin."), _(VERSION), _("Author"))

//Search for a file in the application data or config plugin directories,
gchar* find_plugin_file(const char* filename){
    gchar *fname=NULL;
    fname = g_build_path(G_DIR_SEPARATOR_S,geany_data->app->configdir,"plugins",filename,NULL);

    if (!g_file_test(fname, G_FILE_TEST_IS_REGULAR) ) {
        g_free(fname);
        /* Maybe the file we want is in the data directory instead? */
        fname = g_build_path(G_DIR_SEPARATOR_S,geany_data->app->datadir,"plugins",filename,NULL);

        /* Check again... */
        if (!g_file_test(fname, G_FILE_TEST_IS_REGULAR) ) {
            g_free(fname);
            fname=NULL;
            g_printerr(_("%s: Can't find supporting file!: %s\n"),PLUGIN_NAME,filename);
            return NULL;
        } else {
            /* Return the plugin module directory */
            return g_build_path(G_DIR_SEPARATOR_S,geany_data->app->datadir,"plugins",NULL);
        }

    }
    /* Return the plugin module directory */
    return g_build_path(G_DIR_SEPARATOR_S,geany_data->app->configdir,"plugins",NULL);
}

//Append a string to the Python sys.path.
int add_to_python_path(const char* path){
    PyObject *sys_path;
    PyObject *py_path;

    sys_path = PySys_GetObject("path"); /* Borrowed reference */
    if (sys_path == NULL) {
        PyErr_Print();
        return -1;
    }

    py_path = PyString_FromString(path);
    if (py_path == NULL) {
        PyErr_Print();
        return -1;
    }

    if (PyList_Append(sys_path, py_path) < 0) {
        Py_XDECREF(py_path);
        PyErr_Print();
        return -1;
    }
    Py_XDECREF(py_path);
    return 0;
}

// Initialize the Python plugin kickstart module.
int init_python_kickstart_module(void){
    PyObject *pName;
    const char* kickstart_module = "gpykickstart";
    const char* kickstart_module_file = "gpykickstart.py";
    const gchar* kickstart_path = find_plugin_file(kickstart_module_file);
    if (kickstart_path == NULL) {
        return -1;
    }

    if (add_to_python_path(kickstart_path) < 0) {
        g_free(kickstart_path);
        return -1;
    }

    pName = PyString_FromString(kickstart_module);
    if (pName == NULL) {
        PyErr_Print();
        return -1;
    }

    pKickstartModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pKickstartModule == NULL) {
        PyErr_Print();
        g_printerr(_("Failed to load the \"%s\" module from the \"%s\" directory.\n"),kickstart_module, kickstart_path);
        g_free(kickstart_path);
        return -1;
    }

    g_free(kickstart_path);
    return 0;
}

/* Clean up the Python plugin kickstart module. */
void cleanup_python_kickstart_module(void){
    Py_XDECREF(pKickstartModule);
}

/* initialise the plugin */
void plugin_init(GeanyData *data){
    printf("Loading the test Python module.\n");
    Py_Initialize();    /* Start the Python interpreter. */
    init_python_kickstart_module();
}

/* Cleanup the plugin when required */
void plugin_cleanup(void){
    cleanup_python_kickstart_module();
    Py_Finalize();
}

If you want the wscript that i am using i can post this as well.