Python ctypes:初始化c_char_p()

4
我写了一个简单的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个回答

8

你使用字符 "bye" 初始化的字符串,将其地址赋值给 charP,第一次初始化后不会重新初始化。

请遵循此处的建议:

但是,您需要小心,不要将它们传递给期望指向可变内存的指针的函数。如果您需要可变内存块,则 ctypes 有一个 create_string_buffer 函数可以以各种方式创建这些块。

"指向可变内存的指针" 正是您的 C 函数所需的,因此您应该使用 create_string_buffer 函数来创建该缓冲区,如文档所述。


谢谢,将其更改为charP = create_string_buffer(“bye”)可以解决我的问题。我应该更仔细地查看文档。 - Mark

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很容易导致缓冲区溢出。


strcpy 和溢出的问题你说得好,下面 Alex 的回答应该也解决了这个问题,我只需要确保我的缓冲区足够大即可。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接