我将“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;
}
答案 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)
但请不要两者兼顾。