I'm using ctypes to access functions in an external C library (I only have the binary and a header file for that, no source). I got this working, all fine so far.
Now, that library can be set up to send events. The setup function in the library expects to be passed a pointer to an event. This is supposed to be used for the Windows-style CreateEvent/WaitForSingleObject signal mechanism or the POSIX-type pthread way (BTW, I'm doing all of this under Linux).
This I now want to use in Python. What I am not clear about:
- How can I create a pthread-style event object in Python that has the correct type so I can pass it to the library, and the library can then set it?
- How can I then monitor this event to have a Python function called each time it is set?
I have no clue about the inner workings of pthread and what actually happens when an event is set, so I have no clue about what kind of object that library really expects from me and what it will do with it. I started digging through the Linux kernel headers to find out how pthread_cond_t etc. are defined, what happens when an event is set and so on, but that turned out to be a pointless chase through header files, tracking struct and union definitions and nested DEFINEs; this is beyond me.
I tried several of the available Python event implementations (see e.g. Event system in Python), but they don't have pthread-type events but their own Pythonic event objects. If I pass one of those to the FT lib, either nothing happens at all or it segfaults, which is understandable, if you wildly mix incompatible types. So none of these implementations is really suited for my case (unless there's another one I missed).
I also tried defining a ctypes blob of binary bytes with the right size (determined by sizeof(pthread_cond_t) etc.); I can pass a pointer to that to the FTlib without any segfaults or Python error, but I can't see any changes to that blob when an event occurs. Of course since I don't know what should happen or which prerequisites have to be provided for this event mechanism to work, I'm totally in the dark here.
So this approach, even though I might get it working eventually, seems pointless, ugly and doesn't make a lot of sense. It also robs me of any mutex functionality the original pthread-event has; so there must be a better, cleaner way.
BTW, there's PyFtdi, a pure Python implementation of FTDI drivers, and some other drivers or wrappers, but these don't help either because they a) don't support the device that I am using (at least none of the special features this device offers) and b) they don't implement the event mechanism at all. So unless there's another implementation that I missed, this is also not the way to go.
Of course I googled and searched SO, but couldn't find any mentioning of someone having implemented this properly, even though I'm sure that has been done before; having to deal with pthread events (or Windows signal, for that matter) issued from a C library doesn't seem a very exotic application to me.
So, at the moment I don't really know where to look and what to try next, I need some inspiration...
Edit: Code snippet in C: Basically, this is what I want to reproduce in Python.
#include <pthread.h>
typedef struct _EVENT_HANDLE
{
pthread_cond_t eCondVar;
pthread_mutex_t eMutex;
int iVar;
} EVENT_HANDLE;
int main() {
EVENT_HANDLE eh; // see type definition above
// initialize event
pthread_mutex_init(&eh.eMutex, NULL);
pthread_cond_init(&eh.eCondVar, NULL);
// This sets up the event notification: parameter 3 is a pointer to the event.
// The driver library will set this event.
ftStatus = FT_SetEventNotification(ftHandle, FT_EVENT_RXCHAR, (PVOID)&eh);
while(1) {
// now, wait for the event to happen; the driver library will set it
pthread_mutex_lock(&eh.eMutex);
pthread_cond_wait(&eh.eCondVar, &eh.eMutex);
pthread_mutex_unlock(&eh.eMutex);
// do stuff...
}
}
Any help appreciated,
Sean