通过 Python 将空终止字符串发送到我的 C 代码

Sending null terminated string to my C code through Python

我正在向我的 BPF C 代码发送字符串,但我不确定传入的字符串是否以 null 结尾。如果不是,有没有办法让它们以空值终止?我将我的代码行发送到 BPF,这样我就可以使用我的 stringCounter 函数手动计算它们,但我一直不幸地陷入了一个永远的循环。这是我的 Python 代码的样子:

b = BPF(src_file="hello.c")

lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello copy.csv","r")
contents = f.readlines()
for i in range(0,len(contents)):
    string = contents[i].encode('utf-8')
    lookupTable[ctypes.c_int(i)] = ctypes.create_string_buffer(string, len(string))

这是我为空终止字符串计数器找到的代码

int stringLength(char* txt)
{
    int i=0,count=0;
    
    while(txt[i++]!='[=12=]'){
        count+=1;
    }
    
    return count;
}

ctypes.create_string_buffer(string, len(string)) 不是零终止的。但是 ctypes.create_string_buffer(string) 是。很容易看出,因为 ctypes.create_string_buffer(string)[-1]b'\x00',而 ctypes.create_string_buffer(string, len(string))string 中的最后一个字节。

换句话说,如果你想要一个以零结尾的缓冲区,让 create_string_buffer 计算出长度。 (它使用来自 Python 字节对象的实际长度,因此如果您担心的话,它不会被内部 NUL 字节所愚弄。)

我不熟悉 BPF 但对于 ctypes,如果您的字符串未被 C 代码修改,则您不需要 create_string_buffer,因为它用于创建可变缓冲区,以及 Python Unicode 和字节字符串总是分别传递以 nul 结尾的 wchar_t*char* 到 C 代码。假设您的函数在 test.dlltest.so:

import ctypes as ct

dll = ct.CDLL('./test')
dll.stringLength.argtypes = ct.c_char_p,
dll.stringLength.restype = ct.c_int

print(dll.stringLength('somestring'.encode()))  # If string is Unicode
print(dll.stringLength(b'someotherstring'))     # If already a byte string

输出:

10
15

请注意,这并不排除在字符串本身中包含 nul,但在这种情况下,您的计数函数将 return 一个较短的值:

print(dll.stringLength(b'some[=12=]string'))  # Output: 4

假设不要求 BPF 对象具有硬编码的 ctypes 类型作为索引和值,您的代码可能会写成以下形式。

with open("hello copy.csv") as file:
    for i,line in enumerate(file):
        lookupTable[i] = string.encode()