0

Sending a string from Python to C++ using Python's ctypes module requires you to parse it as a c_char_p (a char *). I've found I need to use python pure string and not a python unicode string. If I use the unicode string, the variables just get overwritten instead of being sent properly. Here's an example:

C++

void test_function(char * a, char * b, char * c) {
    printf("Result: %s %s %s", a, b, c);
}

Python

... load c++ using ctypes ...

lib.test_function.argtypes = [c_char_p, c_char_p, c_char_p]    
lib.test_function(u'x', u'y', u'z')
lib.test_function('x', 'y', 'z')

Running the above Python code gives the following in stdout:

Result: z z z
Result: x y z

Why is this, is this a quirk of ctypes? What's an elegant way to avoid this quirk if I can am getting unicode strings?

Thanks!

rykardo
  • 175
  • 3
  • 14
  • This should work (and does work for me) in Python 2. ctypes implicitly converts a unicode text string to a byte string using the encoding set by `ctypes.set_conversion_mode(encoding, errors)`. On most systems this defaults to strict ASCII. In Python 3, OTOH, ctypes doesn't automatically convert between byte strings and text strings. – Eryk Sun Dec 04 '14 at 03:55
  • What Python version and platform are you using? – Eryk Sun Dec 04 '14 at 03:57
  • I'm using OSX 10.9 with Python 2.7. I'll look at the ctypes conversion mode and see what it's set as - that is probably my mistake :) – rykardo Dec 15 '14 at 20:04

2 Answers2

2

Try c_wchar instead of c_char: https://docs.python.org/2/library/ctypes.html

user1277476
  • 2,871
  • 12
  • 10
2

C/C++ has no real support for Unicode, so there really isn't anything you can do about it. You must to encode your string as in order to pass them into the C/C++ world: you could use UTF-8, UTF-16, or UTF-32 depending on your use case.

For example, you can encode them as UTF-8 and pass in an array of bytes (bytes in Python and char * in C/C++):

lib.test_function(u'x'.encode('utf8'),
                  u'y'.encode('utf8'),
                  u'z'.encode('utf8'))

Exactly which encoding you pick is another story, but it will depend on what your C++ library is willing to accept.

Community
  • 1
  • 1
Rufflewind
  • 8,545
  • 2
  • 35
  • 55