Python ctypes: 初始化 c_char_p()

4 投票
2 回答
13986 浏览
提问于 2025-04-15 16:49

我写了一个简单的C++程序来说明我的问题:

extern "C"{
    int test(int, char*);
}

int test(int i, char* var){
    if (i == 1){
        strcpy(var,"hi");
    }
    return 1;
}

我把这个程序编译成了一个.so文件。从Python中我调用:

from ctypes import *

libso = CDLL("Debug/libctypesTest.so")
func = libso.test
func.res_type = c_int

for i in xrange(5):
    charP = c_char_p('bye')
    func(i,charP)
    print charP.value

当我运行这个时,我的输出是:

bye
hi
hi
hi
hi

我本来期待的是:

bye
hi
bye
bye
bye

我漏掉了什么呢?

谢谢。

2 个回答

2

我猜测Python在这5次操作中使用的是同一个缓冲区。当你把它设置为“hi”后,就没有再把它改回“bye”。你可以这样做:

extern "C"{
    int test(int, char*);
}

int test(int i, char* var){
    if (i == 1){
        strcpy(var,"hi");
    } else {
        strcpy(var, "bye");
    }
    return 1;
}

不过要小心,strcpy这个函数很容易导致缓冲区溢出。

8

你用字符 "bye" 初始化的字符串,之后你一直在获取它的地址并赋值给 charP,但这个字符串在第一次初始化后并不会重新初始化。

请遵循这里的建议

不过你要小心,不要把这些字符串传给那些需要可变内存指针的函数。如果你需要可变的内存块,ctypes 提供了一个 create_string_buffer 函数,可以用不同的方式来创建这些内存块。

所谓的“可变内存指针”正是你的 C 函数所需要的,因此你应该使用 create_string_buffer 函数来创建这个内存缓冲区,正如文档中所解释的那样。

撰写回答