Is there an extension library?

L

Letbetter, Jason

I'm creating Python extensions for several c/c++ components. I'm using
swig to create the extensions. The biggest challenge so far is working with
the c args between Python and the Python extension. Is there a 3rd party
library of extension helpers that assist in representing c-types between
Python and c? Are there any tips and tricks?

Here are some specific scenarios I am running into.

1) Refrencing and derefrencing:
For example, condsider this c api:

void foo_alloc(void** handle_ptr);
void foo_use(void* handle);

In c &handle. How to get pointer to pointer in Python?
In c *handle_ptr. How to derefrence a pointer in Python?


2) Coercion:
For example, suppose you want to initialize a char array in Python.

buf = CharArray(100)
for i in range(100):
buf = i

The above results in:
"TypeError: CharArray___setitem__() argument 3 must be char, not int"
In c, buf = (char)i, is implicit. How do I do it in Python. Why doesn't
Python make this conversion implicitly?


3) It seems like I'm doing something unatural with my Python extension. It
seems someone else may have already figured out the best way to transform c
arguments between Python and Python extensions genericly.

Thanks,
Jason
 
M

Martin v. =?iso-8859-15?q?L=F6wis?=

Letbetter said:
I'm creating Python extensions for several c/c++ components. I'm using
swig to create the extensions. The biggest challenge so far is working with
the c args between Python and the Python extension. Is there a 3rd party
library of extension helpers that assist in representing c-types between
Python and c? Are there any tips and tricks?

I suggest not to use swig, or any tools - atleast not until you fully
understand how to use these tools (I, for one, don't know how to use
swig, so I don't use it).
1) Refrencing and derefrencing:
For example, condsider this c api:

void foo_alloc(void** handle_ptr);
void foo_use(void* handle);

In c &handle. How to get pointer to pointer in Python?
In c *handle_ptr. How to derefrence a pointer in Python?

I recommend to wrap this in a Python object type:

typedef struct{
PyObject_HEAD
void *handle;
} PyFoo;

Then, in PyFoo_New, invoke foo_alloc, and implement a method PyFoo_use
of the PyFoo objects.
"TypeError: CharArray___setitem__() argument 3 must be char, not int"
In c, buf = (char)i, is implicit. How do I do it in Python. Why doesn't
Python make this conversion implicitly?


Because in Python, characters are *not* numbers (unlike in C). In
Python, characters are strings of length 1.

Again, if you want to store chars in setitem: don't use swig, but
write it yourself.
3) It seems like I'm doing something unatural with my Python extension. It
seems someone else may have already figured out the best way to transform c
arguments between Python and Python extensions genericly.

The best way to transform a C library into a Python extension is to
write the extension module by hand.

Regards,
Martin
 
A

Alex Martelli

I'm creating Python extensions for several c/c++ components. I'm using
swig to create the extensions. The biggest challenge so far is working
with
the c args between Python and the Python extension. Is there a 3rd party
library of extension helpers that assist in representing c-types between
Python and c? Are there any tips and tricks?

The vast SWIG manual, at www.swig.org, does give many tips and tricks;
SWIG also comes with a librayr of helpers such as you request.

Here are some specific scenarios I am running into.

1) Refrencing and derefrencing:
For example, condsider this c api:

void foo_alloc(void** handle_ptr);
void foo_use(void* handle);

In c &handle. How to get pointer to pointer in Python?
In c *handle_ptr. How to derefrence a pointer in Python?

You can use typemaps to ensure "void** handle_ptr" as an
argument becomes a "return value" (some opaque representation
of the resulting void*) in Python, and you'll just pass that
opaque value back into foo_use, no need to dereference.

2) Coercion:
For example, suppose you want to initialize a char array in Python.

buf = CharArray(100)
for i in range(100):
buf = i

The above results in:
"TypeError: CharArray___setitem__() argument 3 must be char, not int"
In c, buf = (char)i, is implicit. How do I do it in Python. Why
doesn't Python make this conversion implicitly?


In Python, "a character" is "a string of length one" and implicitly
converting that to/from "an integer that happens to be the ASCII code
for that character" would be an utter, extremely error-prone design
disaster. Use ord() if you want the ASCII code for the one and only
character in a string of length 1, chr() if you want to make a string
of length one starting from a character's ASCII code. [I don't know
what a CharArray _IS_, and how come you got that weird indirectness
requested, but I'm just answering your questions anyway].

3) It seems like I'm doing something unatural with my Python extension.
It seems someone else may have already figured out the best way to
transform c arguments between Python and Python extensions genericly.

SWIG does a good job (for C). Boost Python does an arguably even
better one (for C++, though -- and you do need a decently standard
compliant C++ compiler that won't choke on abstruse templates; also,
I'm not sure if Boost Python is out yet in a release supporting
Python 2.3 -- when I tried to build from the CVS sources I found
the task quite tiresome).


Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top