ESL python调用C模块时传递unicode字符串报错问题解决

Posted NooBkey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESL python调用C模块时传递unicode字符串报错问题解决相关的知识,希望对你有一定的参考价值。

在是用freeswitch时利用ESL的python调用时传递字符串报错

TypeError: in method ‘ESLconnection_api‘, argument 2 of type ‘char const *‘

是由于python传递的字符串为unicode,在c语言char使用的ascii码方式
在SWIG中做一下转换,代码如下

 

 修改文件esl_wrap.cpp

#####

 

/* for C or C++ function pointers */
//添加定义
#define SWIG_InternalNewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags)


SWIGINTERN int
SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
{
//增加Unicode检查
if (PyUnicode_Check(obj)||PyString_Check(obj)) {
char *cstr; Py_ssize_t len;
PyString_AsStringAndSize(obj, &cstr, &len);
if (cptr) {
if (alloc) {
/*
In python the user should not be able to modify the inner
string representation. To warranty that, if you define
SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
buffer is always returned.

The default behavior is just to return the pointer value,
so, be careful.
*/
#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
if (*alloc != SWIG_OLDOBJ)
#else
if (*alloc == SWIG_NEWOBJ)
#endif
{
*cptr = reinterpret_cast< char* >(memcpy((new char[len + 1]), cstr, sizeof(char)*(len + 1)));
*alloc = SWIG_NEWOBJ;
}
else {
*cptr = cstr;
*alloc = SWIG_OLDOBJ;
}
} else {
*cptr = PyString_AsString(obj);
}
}
if (psize) *psize = len + 1;
return SWIG_OK;
} else {
swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
if (pchar_descriptor) {
void* vptr = 0;
if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
if (cptr) *cptr = (char *) vptr;
if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
if (alloc) *alloc = SWIG_OLDOBJ;
return SWIG_OK;
}
}
}
return SWIG_TypeError;
}

//定义UTF8转换函数
SWIGINTERNINLINE PyObject *
SWIG_FromUTF8CharPtrAndSize(const char* carray, size_t size)
{
if (carray) {
if (size > INT_MAX) {
swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
return pchar_descriptor ?
SWIG_InternalNewPointerObj(const_cast< char * >(carray),pchar_descriptor, 0) : SWIG_Py_Void();
} else {


const unsigned char *ucp = (const unsigned char *)carray;
size_t i;
for (i = 0; i < size; ++i) {
if (ucp[i] >= 0x80) /* UTF-8? */
return PyUnicode_FromStringAndSize(carray, static_cast< int >(size));
}
return PyString_FromStringAndSize(carray, static_cast< int >(size));


}
} else {
return SWIG_Py_Void();
}
}


SWIGINTERNINLINE PyObject *
SWIG_FromCharPtr(const char *cptr)
{
//return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
//调用转换
return SWIG_FromUTF8CharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
}

 

完成后编译即可

freeswitch/libs/esl

make pymod

 

以上是关于ESL python调用C模块时传递unicode字符串报错问题解决的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript模块化与esl

Python Unicode编码

从 python esl 发起会议

python2模块中unicode中的转义控制字符

从 C++ 调用 python 函数时如何将 C++ 类作为参数传递?

打开另一个python文件作为模块时传递参数?