Search code examples
pythoncwxpythonpyqt

Can C programs have Python GUI?


My friend has an application written in C that comes with a GUI made using GTK under Linux. Now we want to rewrite the GUI in python (wxpython or PyQT).

I don't have experience with Python and don't know how to make Python communicate with C. I'd like to know if this is possible and if yes, how should I go about implementing it?


Solution

  • Yes its possible to call 'C' functions from Python.

    Please look into SWIG(deprecated) also Python provides its own Extensibility API. You might want to look into that.

    Also google CTypes.

    LINKS:

    Python Extension

    A simple example: I used Cygwin on Windows for this. My python version on this machine is 2.6.8 - tested it with test.py loading the module called "myext.dll" - it works fine. You might want to modify the Makefile to make it work on your machine.

    original.h

    #ifndef _ORIGINAL_H_
    #define _ORIGINAL_H_
    
    int _original_print(const char *data);
    
    #endif /*_ORIGINAL_H_*/
    

    original.c

    #include <stdio.h>
    #include "original.h"
    
    int _original_print(const char *data)
    {
      return printf("o: %s",data);
    }
    

    stub.c

    #include <Python.h>
    #include "original.h"
    
    static PyObject *myext_print(PyObject *, PyObject *);
    
    static PyMethodDef Methods[] = {
      {"printx", myext_print, METH_VARARGS,"Print"},
      {NULL, NULL, 0, NULL}
    };
    
    PyMODINIT_FUNC initmyext(void)
    {
      PyObject *m;
      m = Py_InitModule("myext",Methods);
    }
    
    static PyObject *myext_print(PyObject *self, PyObject *args)
    {
      const char *data;
      int no_chars_printed;
      if(!PyArg_ParseTuple(args, "s", &data)){
          return NULL;
      }
        no_chars_printed = _original_print(data);
        return Py_BuildValue("i",no_chars_printed);  
    }
    

    Makefile

    PYTHON_INCLUDE = -I/usr/include/python2.6
    PYTHON_LIB = -lpython2.6
    USER_LIBRARY = -L/usr/lib
    GCC = gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/include -I/usr/include/python2.6 
    
    win32 : myext.o
        - gcc -shared myext.o $(USER_LIBRARY) $(PYTHON_LIB) -o myext.dll
    
    linux : myext.o
        - gcc -shared myext.o $(USER_LIBRARY) $(PYTHON_LIB) -o myext.so
    
    myext.o: stub.o original.o
        - ld -r stub.o original.o -o myext.o
    
    stub.o: stub.c
        - $(GCC) -c stub.c -o stub.o
    
    original.o: original.c
        - $(GCC) -c original.c -o original.o
    
    clean: myext.o
        - rm stub.o original.o stub.c~ original.c~ Makefile~
    

    test.py

    import myext
    myext.printx('hello world')
    

    OUTPUT

    o: hello world