我有一个简单的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”字符串?
答案 0 :(得分:11)
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
就像一个const指针。如果用作restype
,您实际上将获得Python str
。所以对于initializetest
,它将从分配的内存中创建一个字符串(通过复制数据)并将指针扔掉。
现在我们正在创建一个新类型,POINTER
到c_char
。然后在两个函数中使用它。
对于Python,此类型指向一个char,因此我们必须在searchtest
完成后将其强制转换为整个字符串。我们转换为c_char_p
因为我们只想读取值,所以const指针就可以了。
作为旁注,这说明了将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
设置行,因为如果使用Python ctypes
作为参数,c_char_p
会假定为str
。
答案 1 :(得分:1)
也许使用像described here
这样的重新定义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()
编辑:测试后纠正:)
答案 2 :(得分:0)
将c_char_p设置为init func的返回类型。 c_char_p表示char *(NUL终止)