开发者社区> 问答> 正文

Python的C扩展 argument 1 must be string without null bytes, not str

a123456678 2016-06-08 14:34:29 1234

我的场景是这样的:
我用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里面二进制和字符集有区别呢?

分享到
取消 提交回答
全部回答(1)
  • a123456678
    2019-07-17 19:31:56

    在 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' 完全不会造成问题。

    0 0

集结各类场景实战经验,助你开发运维畅行无忧

推荐文章
相似问题