[Python-3000] Possible py3k problem resolved.

Thomas Heller theller at ctypes.org
Wed Nov 19 20:27:24 CET 2008

Lambert, David W (S&T) schrieb:
> Martin's "read the manual" answer is quite satisfying.
> Unfortunately, it doesn't fix core dump of Issue4309.
> I became excited thinking the problems could be related.

Issue4309 is basically this problem calling the printf function:

  libc = CDLL(find_library("c"))
  printf = libc.printf
  - segfault -

> I appreciate your incite,
> Dave.

The behaviour is explained in the docs, but you have to read
it very 'carefully' (and maybe it should be changed for python 3):

  "None, integers, byte strings and unicode strings are the only native 
  Python objects that can directly be used as parameters in these function 
  calls. None is passed as a C NULL pointer, byte strings and unicode 
  strings are passed as pointer to the memory block that contains their 
  data (char * or wchar_t *). Python integers are passed as the platforms 
  default C int type, their value is masked to fit into the C type."

When you write
you are passing a /unicode string/ in Python 3, a /byte string/ in Python 2.x.

In Python 3 the printf C-function thus will receive a 'wchar_t *' pointer
and so may crash or produce garbage since it must be called with a 'char *' pointer.

These are the possible solutions for py3:

1. set the argtypes attribute for the printf function, and the first argument
   will automatically be converted to a valid 'char *' pointer, or an exception
   is raised if no conversion is possible:
       printf.argtypes = [c_char_p]
       printf("foo\n"); printf(b"foo\n"); ...

2. Pass a bytes string instead of a (normal, unicode) string

3. Wrap the argument into a c_char_p() instance

You have already mentioned the latter two solutions in the bug tracker.
The first solution has the advantage that it is works for Python 2.x
AND Python 3, and also has other advantages.


More information about the Python-3000 mailing list