Calling a C-Library from within Python

When I was experimenting with python a while ago, I wanted to move the mouse pointer from inside python. Since this didn’t seem to be possible, I  found a workaround which used a c-call to X11/Xlib to actually move the mouse pointer. This really worked great and I will use this as an example to show how to call a c-function from within python.

First, here’s the c-file containing a method to move the mouse pointer:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
void mouseMove(int x, int y)
{
Display *displayMain = XOpenDisplay(NULL);
if(displayMain == NULL)
{
fprintf(stderr, “no Display !!!\n”);
exit(EXIT_FAILURE);
}
XWarpPointer(displayMain, None, None, 0, 0, 0, 0, x, y);
XCloseDisplay(displayMain);
}

when compiled, this gives us a share-library called mouse.so.
Now, on the python side, we have to import some c-specific stuff first:

from ctypes import cdll,c_int

and can then load the library as follows:

lib = “/path/to/mouse.so”
dll = cdll.LoadLibrary(lib)

and finally map the function call like this:

mouseMove = (lambda x,y: dll.mouseMove(c_int(x), c_int(y)))

now we can move our mouse-pointer from within python by calling mouseMove()

mouseMove(xshift, yshift)

Advertisements
9 comments
  1. Nick said:

    Excellent post, just what I was looking for. Thanks!

  2. BlackForestCowboy said:

    Dont know whether its important, but it works with dylibs as well.

  3. ka010 said:

    Shure, .dylib is the mac equivalent to a windows .dll .It depends on the platform what kind of extension the library will have.
    Shared-objects (.so) are working on mac osx as well.

  4. igor_t said:

    Hm, doesn’t work for me. It writes:
    Traceback (most recent call last):
    File “mouse.py”, line 9, in
    lib = mouse.so
    NameError: name ‘mouse’ is not defined

    What have I done wrong?

    • ka010 said:

      Yeah, i’ve fucked up here,of course the assignment should look like this:
      lib = “/path/to/mouse.so”

      It should work then, thanks for dropping a comment.

  5. Ronny said:

    Brilliant post, thanks! Works perfect on python 2.5.

  6. Aasha said:

    i tried above code for simple add() function in C.

    compiled it and got .so file

    followed rest of the commands.

    but at the end wen tried
    add(2,3) as function call

    got output as 51
    i suppose 5 is addition and 1 is some return value.

    i want to eliminate this return value. what m i supposed to do?

    • ka010 said:

      I’m not sure about that return value, what does your c code look like ? The code below works fine for me.

      add.c

      #include
      #include

      int add(int a, int b) {
      return a+b;
      }

      make shared library
      gcc -shared -o add.so add.c

      test.py
      from ctypes import cdll,c_int
      lib = "add.so"
      dll = cdll.LoadLibrary(lib)
      add = (lambda x,y: dll.add(c_int(x), c_int(y)))
      print add(3,5)
      print add(2,1)

      test
      $ python test.py
      8
      3

  7. Aasha said:

    ok..

    my add function was with no return value..

    void add(int a,int b)
    {
    printf(“ADDITION IS %d”,a+b);
    }

    in this case i got the problem mentioned in above comment..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: