我的场景是这样的:
我用Python的socket接收tcp的一个数据包,这个数据包里面有4个字节的包体长度、head结构体和body结构体(数据是由C语言端发送过来的)。当接收到这个数据包的时候原封不动的传给一个我写的Python扩展来解析这个数据包,当我把这个数据包当参数传给Python扩展函数的时候报TypeError: argument 1 must be string without null bytes, not str。
是不是这样的数据包有什么不一样的么?二进制的包如何用Python的一些库处理然后作为参数传给扩展处理呢?
Python代码片段如下:
def msgProc(self, sockId, data):
"process incoming msg"
#may need to rewrite the message lib
pydecode.decode(data)
其中data是从socket receive 到的,没经过任何加工,直接传给pydecode扩展下的decode函数。
C代码片段如下:
static PyObject* record_decode(PyObject *self, PyObject *args)
{
char *pszData;
char *buffer;
if (!PyArg_ParseTuple(args, "s", &buffer)) {
printf("param error\n");
return NULL;
}
'''
do something here
'''
}
执行时抛出这样的错误:argument 1 must be string without null bytes, not str。
看报错应该是类型传得不对,在Python里边,string和str区别貌似不一样?data是纯C申请的一个char *类型,然后保存包体的长度以及一些结构体,然后经过memcpy复制后经过socket传过来的,这边Python接收端收到的应该是二进制吧?是不是在Python里面二进制和字符集有区别呢?
在 Python 3 里,字符串类型名为 str。它就是用来表示字符串的,真正的字符串,比如你现在看到的这串字符。不应当用来表示任何其它的数据。其内部表示你不需要关心,只需要知道它使用的是 Unicode 就好。
Python 3 有另一与字符串相关的类型叫 bytes。顾名思义,它是字节串,即一堆字节。一堆字节是啥呢?Python 也不知道;你得告诉它。比如你知道它是一段 UTF-8 编码的中文,那么用 .decode('utf-8') 解释之后就得到了一个字符串。如果它是一个特定的结构体,你可以使用 struct 模块来进行解析。等等。
C 里的 char 是啥呢?其实就是以 '0' 表示结束的一堆字节,而这个结尾表示还只对 str 系列函数有效。当然通常 char* 是用来表示(已编码的)字符串的,但是也经常被用来放其它数据结构。
所以,Python 3 里的 bytes 类型基本对应于 C 的 char*,只不过 bytes 里包含 '0' 完全不会造成问题。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。