I made a wxPython gui to interact with a camera, however the lab is very matlab centric and the professor wants everything to be controllable from matlab.

I think this is more of a matlab problem, but it's python related and I thought it might be a little odd to go to a matlab forum to ask questions about what I can do to use matlab as little as possible. Actually it might be an issue with c, although I'm heavily embedding python in c...anyway, I'm sorry if this isn't the place to ask.

I can embed python into a c file, have matlab compile a mex file from it, and load a module then call a non graphical python function from it just fine. In my case I can write hello world to a file. However when I try to use wxPython in the python function matlab just crashes the moment I call the mex file. This is the code I used

mat_function.c

#include <Python.h>
#include <mex.h>

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[])
{
    PyObject *pName, *pModule, *pDict, *pFunc, *pValue;

    Py_Initialize();

    pName = PyString_FromString("py_function");
    
    PyRun_SimpleString("import sys");
	PyRun_SimpleString("sys.path.append(\"/home/jarl/embed_python/\")");

    pModule = PyImport_Import(pName);

    pDict = PyModule_GetDict(pModule);

    pFunc = PyDict_GetItemString(pDict, "run");

    if (PyCallable_Check(pFunc)) 
    {
        PyObject_CallObject(pFunc, NULL);
    } else 
    {
        PyErr_Print();
    }

    Py_DECREF(pModule);
    Py_DECREF(pName);

    Py_Finalize();
}

py_function.py

import wx

def run():
	app = wx.App()

	frame = wx.Frame(None, -1, 'simple.py')
	frame.Show()

	app.MainLoop()

You could use os.system calls in your wxPython GUI to run Matlab from the command line. You can dump data into a text file (making sure to put an exit command at the end of the file otherwise the Matlab automation window won't close) and then call

os.system('matlab -automation -r myMfile')

If the commands are written as a string of commands separated by semicolons you can simply replace myMFile with the string of commands.

You also have to make sure that myMfile is on the Matlab path (If you are on windows the easiest way is to add it to the MATLAB folder in My Documents). Any matlab call will unfortunately open a hidden matlab automation window. You can not easily get around Matlab opening up in some form, but at least this way it won't pop up on the screen.

Sorry that I forgot to mention this before, but if you choose to outsource work load to matlab you would also want to use the -wait argument in the command line call. Just to be safe!

Hi! I tried it, but it doesn't work. PyImport_Import always return a NULL value. I supose that it is a path problem. If I try to import a core python module (sys, os, ..) the import works fine, but if I try to import other module (wx for example) it returns NULL.

Replacing mex function by main and compiling with gcc, it works. Do you need configure any matlab path? What version of Matlab did you use? I'm using Matlab R2009b and Ubuntu 10.04.

Sorry for my English!

Hi! I tried it, but it doesn't work. PyImport_Import always return a NULL value. I supose that it is a path problem. If I try to import a core python module (sys, os, ..) the import works fine, but if I try to import other module (wx for example) it returns NULL.

Replacing mex function by main and compiling with gcc, it works. Do you need configure any matlab path? What version of Matlab did you use? I'm using Matlab R2009b and Ubuntu 10.04.

Sorry for my English!

I once found a trick (not matlab related): Before importing a module in C, you can import it with python

PyRun_SimpleString("import wx");
mod = PyImport_ImportModule("wx");

The aim of the PyRun_SimpleString is to put wx in sys.modules. The trick may work for you.

I think that the issue is related with Matlab. I try to execute this code:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    PyObject *mod;

    Py_Initialize();

    PyRun_SimpleString("import wx");
    mod = PyImport_ImportModule("wx");
    if (mod == NULL)
        mexErrMsgTxt("Error");
    else
        mexPrintf("OK");
    ...
    Py_Finalize();
}

Compiling command:

mex python.c -lpython2.6

When I launch it from Matlab, I get the follow output:

>> python()
??? Error using ==> python
Error

However, if I compile the same code in C, it works:

void main()
{
    PyObject *mod;

    Py_Initialize();

    PyRun_SimpleString("import wx");
    mod = PyImport_ImportModule("wx");
    if (mod == NULL)
        printf("Error");
    else
        printf("OK");
    ...
    Py_Finalize();
}

Thanks in advantage!

I tried to launch Matlab from terminal and reviewed the output:

$ matlab &
$ Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/__init__.py", line 45, in <module>
    from wx._core import *
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 4, in <module>
    import _core_
ImportError: /usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core_.so: undefined symbol: PyExc_ValueError

I have problems with non-pure python modules (wx, igraph, ...), but it works fine with pure python modules (reportlab, sys, os, ...).

Any idea?

Thanks a lot!

I tried to launch Matlab from terminal and reviewed the output:

$ matlab &
$ Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/__init__.py", line 45, in <module>
    from wx._core import *
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 4, in <module>
    import _core_
ImportError: /usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core_.so: undefined symbol: PyExc_ValueError

I have problems with non-pure python modules (wx, igraph, ...), but it works fine with pure python modules (reportlab, sys, os, ...).

Any idea?

Thanks a lot!

Didn't you forget to link something against -lpython ?

Didn't you forget to link something against -lpython ?

I'm using -lpython2.6 option instead of -lpython

I'm using -lpython2.6 option instead of -lpython

It's probably stupid, but perhaps you should also link against wx/_core_.so ?

It's probably stupid, but perhaps you should also link against wx/_core_.so ?

It works (I love the stupid ideas)! But it occurs with all shared libraries. I did it:

$ ln -s /usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core_.so libcore.so
$ mex python.c -lpython2.6 -L. -lcore

If you check shared library dependencies (with ldd) you'll see all wx dependencies (wx, cairo, X11, ...). It's important append to LD_LIBRARY_PATH the libcore.so directory and launch matlab from the shell:

$ export LD_LIBRARY_PATH=.
$ matlab &

It works but the similar problem appears with gdi library :(

$ Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/__init__.py", line 45, in <module>
    from wx._core import *
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 14771, in <module>
    from _gdi import *
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_gdi.py", line 4, in <module>
    import _gdi_
ImportError: /usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_gdi_.so: undefined symbol: PyExc_ValueError

I will need to do this with each library.

Let us know if it finally works when you add all the libraries. It could become a famous receipe for using python from matlab !

I discovered that it appears the same error with C if you're using dynamic link on runtime. I created libwx.so:

int wx()
{
    PyObject *pModule;

    Py_Initialize();

    PyRun_SimpleString("import wx");
    pModule = PyImport_ImportModule("wx");

    if (pModule == NULL)
        return -1;

    Py_Finalize();
    return 0;
}

And I tried to dynamic link:

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main()
{
	void *lib_handle;
	int (*fn)(void);
	char *error;

	lib_handle = dlopen("libwx.so", RTLD_NOW);
	if (!lib_handle)
	{
		fprintf(stderr, "%s\n", dlerror());
		exit(1);
	}

	fn = dlsym(lib_handle, "wx");
	if ((error = dlerror()) != NULL)
	{
		fprintf(stderr, "%s\n", error);
		exit(1);
	}

	if((*fn)() < 0)
		printf("No import\n");
	else
		printf("OK\n");

	dlclose(lib_handle);
}

And the result is the same:

$ ./test 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/__init__.py", line 45, in <module>
    from wx._core import *
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 4, in <module>
    import _core_
ImportError: /usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core_.so: undefined symbol: PyExc_ValueError
No import

Note: compiling command

gcc -c libwx.c -o libwx.o -fPIC
gcc -shared libwx.o -o libwx.so -lpython2.6
gcc test.c -o test -ldl

So, it's really a C (and Python API) problem and not a Matlab problem.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.