【发布时间】:2019-03-12 18:05:45
【问题描述】:
问题
我正在尝试使用ctypes 在 Python 中使用 C 函数。函数reverse 应该将stri 的反向版本写成stro。
rev.c:
#include <stddef.h>
/* length is the length of the string EXCLUDING the \0 terminator
*/
void reverse(char * stro, char * stri, size_t length)
{
for(size_t i=0; i<length; i++) stro[i]=stri[length-1-i];
stro[length]='\0';
}
rev.py:
from ctypes import *
revlib = cdll.LoadLibrary("rev.so");
reverse = revlib.reverse
reverse.argtypes = [c_char_p, c_char_p, c_size_t]
hello = "HelloWorld"
stri = create_string_buffer(hello)
stro = create_string_buffer(b'\000' * (len(hello)+1))
reverse(stro, stri, len(stri))
print(repr(stri.value))
print(repr(stro.value))
我用gcc -o rev.so -shared -fPIC rev.c编译了c文件,调用了export LD_LIBRARY_PATH=.,然后我尝试了上面的python脚本。这是输出:
$ python rev.py
'HelloWorld'
''
我预计第二行是'dlroWolleH'。我避免使用空格,以防它们会引起问题。
我尝试过的
我用gcc rev.c -Wall -Wextra -std=c11 -pedantic编译了上面的c函数,它没有产生任何警告。
当我使用这个主要功能时,这个功能似乎可以工作:
int main() {
char * str = "Hello, World";
char o[100];
reverse(o, str, strlen(str));
puts(str);
puts(o);
}
产生这个输出:
$ gcc rev.c; ./a.out
Hello, World
dlroW ,olleH
只是为了尝试成功写入缓冲区,我尝试了sscanf,如下所示:
libc = cdll.LoadLibrary("libc.so.6")
stri = create_string_buffer(100)
libc.sscanf("HelloWorld", "%s", stri)
print(repr(stri.value))
这会打印出预期的结果。但我的函数似乎无法写入缓冲区。
我做错了什么?
【问题讨论】:
-
在 Python 中字符串是不可变的,这意味着它们不能被改变。我建议你修改你的 C 函数以返回一个值。
-
@martineau OP 正在写入 ctypes 字符串缓冲区,而不是 Python 字符串
-
@meowgoesthedog:我意识到了。