need assistance with C extesion
djw
dwelch91 at no.spam.attbi.com
Tue Feb 11 12:24:12 EST 2003
Hello all,
I am having some difficulty creating a C extension on RH8/Py2.2.1. I am
trying to hand write a C wrapper to wrap an existing library that has an
API that doesn't seem to be conducive to being made into a Python
extension (I don't really have the option of changing the API).
The problem, I think, boils down to the fact that the API passes
pointers to structs that contain pointers to functions.
My attempts to use SWIG on this have all failed.
Here is the essence of the API:
/* The structure that contains pointers to functions. */
struct ptalProvider_s {
char *name;
int sizeofDevice;
int sizeofChannel;
ptalDevice_t (*deviceOpen)(char *devname,int lenPrefix);
void (*deviceConstructor)(ptalDevice_t dev,void *cbd);
void (*deviceDestructor)(ptalDevice_t dev);
void (*deviceDump)(ptalDevice_t dev,int level);
int (*deviceGetDeviceIDString)(ptalDevice_t dev,
char *buffer,int maxlen);
int (*deviceGetPreviousDeviceIDString)(ptalDevice_t dev,
char *buffer,int maxlen);
void (*channelConstructor)(ptalChannel_t chan);
void (*channelDestructor)(ptalChannel_t chan);
void (*channelDump)(ptalChannel_t chan,int level);
int (*channelIsOpen)(ptalChannel_t chan);
int (*channelOpen)(ptalChannel_t chan);
int (*channelClose)(ptalChannel_t chan);
int (*channelSelect)(ptalChannel_t chan,int *pr,int *pw,int *px,
struct timeval *timeout);
int (*channelRead)(ptalChannel_t chan,char *buffer,int count);
int (*channelWrite)(ptalChannel_t chan,char *buffer,int count);
int (*pmlOpen)(ptalDevice_t dev);
int (*pmlClose)(ptalDevice_t dev);
int (*pmlGet)(ptalPmlObject_t obj,ptalPmlObject_t next);
int (*pmlSet)(ptalPmlObject_t obj);
int (*pmlSetTrap)(ptalPmlObject_t obj,int enable);
int (*pmlServiceTraps)(ptalDevice_t dev);
};
/* A pointer type for the above structure */
typedef struct ptalProvider_s *ptalProvider_t;
/* A representative function declaration in the API. */
int ptalDeviceEnumerate(ptalProvider_t provider, ptalDeviceEnumerate_f
callback,void *cbd);
/* Another structure that is used. */
struct ptalDevice_s {
ptalDevice_t prev,next;
ptalProvider_t provider;
char *devname; /* dynamically allocated */
int lenPrefix; /* length of provider name and colon(s) */
void *appInfo; /* application private data */
ptalFile_t configFile;
ptalChannel_t firstChannel;
ptalChannel_t lastChannel;
ptalChannel_t pmlChannel;
ptalPmlObject_t firstPmlObject;
ptalPmlObject_t lastPmlObject;
};
/* Pointer to a device struct */
typedef struct ptalDevice_s *ptalDevice_t;
/* Sample APIs for devices */
ptalDevice_t ptalDeviceOpen(char *name);
int ptalDeviceClose(ptalDevice_t dev);
In this API, there are 2 additional structures and cooresponding
(pointer) types (channels and pmlobjects) that are passed back and
forth. The C code that I have seen that uses this API defines variables
that are of type "ptalDevice_t" (for example) and then passes it into a
function. Because of the embedded C function pointers, SWIG seems to
balk at this. (And I don't know how to hand code it either).
I have a couple of ideas on how to handle this, but they both seem
pretty kludgy.
First, I though, maybe just declare a one or a few global instances of
each _t pointer that I need in the C wrapper code. This would require
that some severe limitations be placed on the code, for example, only 1
device can be used at a time (cooresponding to the 1 instance declared
in the C wrapper) or n number of channels available. This is too
restrictive for what I need, though.
So, I thought, maybe there needs to be some sort of storage and access
mechanism in the C wrapper (STL maps, maybe?) and a way of referring to
them, like handles or descriptors. I would have to add some API kruft to
create and destroy the handles so that the underlaying C objects will be
created and destroyed. Maybe that would work, but seems pretty messy and
has the potential to hide memory leaks and the like.
I still don't understand if there is a way to use "opaque" pointers to
the structures and have the pointers "flow" through Python code
unaffected. If there is, I don't know how to appoach it.
Are there other ways to handle this that I can't seem to conjure up?
Any and all help is much appreciated.
Thanks,
Don
PS. Yes, I have done my homework: searched with Google, Google Groups,
consulted every Python book I own, and haven't found the answer.
More information about the Python-list
mailing list