类型和字符串

2024-04-18 20:56:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个简单的C文件:

char* initializetest() {
    char * test = malloc(1000);
    return test;
}

int searchtest( char* test )
{
   strcpy(test,"test");
   return 0;
}

main()
 {
    char *test = initializetest();
    searchtest(test);
    printf("%s\n", test );
}

和python文件:

from ctypes import *

class Test(object):
    def __init__(self):
        self.test_library=CDLL("test.so")
        self.test_initialize = self.test_library.initializetest
        self.test_search = self.test_library.searchtest
        self.test_search.restype=c_int
        self.m = self.test_initialize()

    def search(self):
        self.test_search(self.m)
        print self.m

r = Test()
print r.search()

如何在python中获取“test”字符串?


Tags: 文件testselfsearchreturndeflibraryint
2条回答
from ctypes import *

charptr = POINTER(c_char)

test = CDLL('test.so')
test.initializetest.argtypes = []
test.initializetest.restype = charptr
test.searchtest.argtypes = [charptr]
test.searchtest.restype = c_int

buf = test.initializetest()
test.searchtest(buf)
print cast(buf, c_char_p).value
# TODO Release the "buf" memory or it will leak.

编辑

最初我使用c_char_p在函数之间传递缓冲区,但是c_char_p就像一个常量指针。如果用作restype,实际上会得到一条Pythonstr。因此对于initializetest,它将从分配的内存中创建一个字符串(通过复制数据)并丢弃指针。

现在我们正在创建一个新类型,从POINTERc_char。然后在这两个函数中使用。

对于Python,这种类型指向一个字符,因此我们必须在完成searchtest之后对其进行强制转换以获取整个字符串。我们强制转换为c_char_p,因为我们只想读取值,这样常量指针就可以了。

顺便说一下,这说明了对修改数组的函数使用c_char_p的灾难性影响(正如上面的searchtest):

>>> libc.memset.argtypes = [c_char_p, c_int, c_int]
>>> foo = 'Python'
>>> foo
'Python'
>>> libc.memset(foo, ord('x'), 3)
44808532
>>> foo
'xxxhon'
>>>

注意我们是如何成功地更改了一个不可变的Python字符串的!

甚至不需要argtypes设置行,因为ctypes假设c_char_p如果使用Pythonstr作为参数。

也许通过使用像described here这样的restype

class Test(object):
    def __init__(self):
        self.test_library=CDLL("./test.so")
        self.test_initialize = self.test_library.initializetest
        self.test_initialize.argtypes = []
        self.test_initialize.restype = c_char_p # c_char_p is a pointer to a string
        self.test_search = self.test_library.searchtest
        self.test_search.restype = c_int
        self.test_search.argtypes = [c_char_p]
        self.m = c_char_p(self.test_initialize())

    def search(self):
        return self.test_search(self.m).value

r = Test()
print r.search()

编辑:测试后更正:)

相关问题 更多 >