Char * в C ++ от swig получил проблему в Python 3.0 - PullRequest
1 голос
/ 11 мая 2010

Наша библиотека C ++ прекрасно работает с Python2.4, используя Swig, возвращая символ C ++ * обратно в строку Python. Но это решение проблемы проблема в Python3.0, ошибка:

Исключение = (, UnicodeDecodeError ('utf8', b "\ xb6 \ x9d \ xa .....", 0, 1, "байт неожиданного кода")

Наше определение похоже на (работает нормально в Python 2.4):

void  cGetPubModulus(
 void*  pSslRsa,
    char*  cMod,
    int*   nLen );

%include "cstring.i"
%cstring_output_withsize( char* cMod, int* nLen );

Подозреваемый swig автоматически выполняет преобразование Bytes-> Str. В python2.4 это может быть неявным, но в Python3.0 это долго не разрешается .. У кого-нибудь есть хорошая идея? спасибо

Ответы [ 2 ]

3 голосов
/ 31 июля 2011

Я столкнулся с подобной проблемой. Я написал карту типов SWIG для пользовательского массива char (фактически unsigned char), и он получил SEGFAULT при использовании Python 3. Поэтому я отладил код в карте типов и понял, что Леннарт обнаружил проблему.

Мое решение этой проблемы заключалось в следующем в этой карте типов:

%typemap(in) byte_t[MAX_FONTFACE_LEN] {
   if (PyString_Check($input))
   {
     $1 = (byte_t *)PyString_AsString($input);
   }
   else if  (PyUnicode_Check($input))
   {
     $1 = (byte_t *)PyUnicode_AsEncodedString($input, "utf-8", "Error ~");
     $1 = (byte_t *)PyBytes_AS_STRING($1);
   }
   else
   {
     PyErr_SetString(PyExc_TypeError,"Expected a string.");
     return NULL;
   }
}   

То есть я проверяю, что это за строковый объект PyObject. Функции PyString_AsString() и PyUnicode_AsString() вернут > 0, если их ввод будет строкой UTF-8 или Unicode соответственно. Если это строка Unicode, мы конвертируем эту строку в байты при вызове PyUnicode_AsEncodedString(), а позже мы конвертируем эти байты в char * с помощью вызова PyBytes_AS_STRING().

Обратите внимание, что я смутно использую эту же переменную для хранения строки в юникоде и преобразования ее позже в байты. Несмотря на то, что это было так сомнительно и, возможно, это могло произойти в другом обсуждении стиля кодирования, факт в том, что я решил свою проблему. Я протестировал его с двоичными файлами python3 и python2.7 без каких-либо проблем.

И, наконец, последняя строка предназначена для репликации исключения в вызове python, чтобы сообщить, что входные данные не были строкой, ни utf, ни unicode.

3 голосов
/ 20 февраля 2011

Это скорее Python 3, который делает это преобразование. В Python 2 байты и str - это одно и то же, в Python 3 str - это Unicode, поэтому что-то где-то пытается преобразовать его в Unicode с UTF8, но это не UTF8.

Ваш код Python 3 должен возвращать не строку Python, а байты Python. Это не будет работать с Python 2, так что вам нужны операторы препроцессора для обработки различий.

...