字符串连接使用ctypes附加垃圾字符

时间:2011-03-20 16:35:31

标签: python string ctypes string-concatenation

我将“00000000”附加到一个字符串,它第一次正常工作。但是,当第二次运行“垃圾字符”而不是“000000”时。这是我在实际程序中如何做的示例代码。

档案one.py

# File One.py
from two import *

def One():
    while(1):
        key = Two()
        key = key + "00000000"
        print key

def main():
    One()

if __name__ == "__main__":
    main()

档案二.py

from ctypes import *
import binascii

handle = None

def Two():
    global handle
    libc = CDLL('libthree.so', DEFAULT_MODE, handle) 
    if not handle: 
        handle = libc._handle

    buffer = create_string_buffer(16)
    libc.Three(buffer)
    return binascii.b2a_hex(buffer)

文件three.c - 生成libthree.so

#include "stdio.h"
#include "stdlib.h"

void Three(char * buffer)
{
    long value = 0x78563412;
    memcpy(buffer,&value,4);
    memcpy(buffer + 4,&value,4);
    memcpy(buffer+ 8,&value,4);
    memcpy(buffer+ 12,&value,4);
    return;
}

int main()
{
    return 0;
}

1 个答案:

答案 0 :(得分:1)

create_string_buffer可以使用字符串或长度进行初始化。如果使用字符串s初始化,则为len(s)+1字符分配空间,以便可以追加终止空值。但是如果用整数值初始化,create_string_buffer假定你是人类,你必须知道你在做什么,并分配这么多的空间。不幸的是,你的C代码写入了16个字符的空格,所以没有空终止符。当这对您有用时,纯粹意外的是,分配的存储之后的字节恰好是0(null),终止字符串。稍后,该内存被用于其他东西,然后你得到了垃圾。请尝试使用create_string_buffer(16+1)代替,看看情况是否有所改善。

文档还建议使用返回的字符串缓冲区对象的.string()方法,以便显式应用以null结尾的语义 - 替代方法是.raw(),它将读取过去的空值直到定义的缓冲区尺寸。具有讽刺意味的是,如果指定key = key.raw() + "000000",这可能会为您提供最初指定的16个字符大小的缓冲区,并以此方式绕过垃圾字符。

所以你可以尝试两件事:

在One中,做:

key = key.raw() + "00000000"

或者在两个中,改为:

buffer = create_string_buffer(16+1)

但请不要两者兼顾。