2010-05-11 4 views
1

Notre bibliothèque C++ fonctionne très bien avec Python2.4 en utilisant Swig, retournant un char * C++ à une chaîne python. Mais cette solution problème frappé dans Python3.0, l'erreur est:Le char * de C++ par swig a un problème avec Python 3.0

Exception = (, UnicodeDecodeError ('utf8', b "\ XB6 \ x9d \ xa .....", 0, 1, « octet de code inattendu «)

Notre définition est comme (fonctionne bien en Python 2.4):.

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

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

rasade suspect fait un Bytes-> conversion Str automatiquement python2.4 il peut être implicite mais Python3.0

Répondre

3

C'est plutôt Python 3 qui fait cette conversion. tes et str sont la même chose, dans Python 3 str est unicode, donc quelque part essaie de le convertir en Unicode avec UTF8, mais ce n'est pas UTF8.

Votre code Python 3 doit renvoyer non pas une chaîne Python, mais un octet Python. Cela ne fonctionnera pas avec Python 2, vous aurez donc besoin d'instructions de préprocesseur pour gérer les différences.

3

J'ai rencontré un problème similaire. J'ai écrit un typage SWIG pour un tableau personnalisé char (un unsigned char en fait) et il a obtenu SEGFAULT lors de l'utilisation de Python 3. J'ai donc débogué le code dans le typemap et j'ai réalisé le problème que Lennart déclare.

Ma solution à ce problème a été fait ce qui suit dans ce typemap:

%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; 
    } 
} 

C'est, je vérifie quel type d'objet chaîne est PyObject. Les fonctions PyString_AsString() et PyUnicode_AsString() renverront > 0 si leur entrée est une chaîne UTF-8 ou une chaîne Unicode respectivement. Si c'est une chaîne Unicode, nous convertissons cette chaîne en octets dans l'appel PyUnicode_AsEncodedString() et plus tard, nous convertissons ces octets en char * avec l'appel PyBytes_AS_STRING().

Notez que j'utilise vaguement la même variable pour stocker la chaîne unicode et la convertir plus tard en octets. En dépit d'être si discutable et peut-être, il pourrait dériver dans une autre discussion de style de codage, le fait est que j'ai résolu mon problème. Je l'ai testé avec les binaires python3 et python2.7 sans aucun problème pour le moment. Enfin, la dernière ligne est pour la réplication d'une exception dans l'appel python, pour informer que cette entrée n'était pas une chaîne, ni utf ni unicode.

Questions connexes