C函数的Ctype返回类型
我有一个C语言的函数,如下所示:
char* hash_id_G1(char *str){
char hash[20];
...
return hash;
}
我需要一些像这个函数一样的功能,它们可以接收一个字符数组,并返回一个字符数组或者字符的指针。
我会把这些编译成一个共享库,然后用ctypes导入到Python中。
这是我到目前为止的做法:
from ctypes import *
ibc = cdll.LoadLibrary('./libibc.so.1.0.1')
strin = 'sometext to hash'
ids = (c_char * 40)()
ids.value = strin
hash = c_char_p
hash_id = ibc.hash_id_G1
hash_id.restype = c_char_p
hash = hash_id(ids)
这个库运行得不错,但我无法设置返回值类型。当我尝试设置时,代码就崩溃了,出现了段错误。
我需要从Python中逐个调用C库里的函数。这些函数通常返回加密结果。我该如何定义这些函数,以便它们能接受来自ctypes接口的字符串,并以某种可存储的形式返回加密结果呢?
任何帮助都非常感谢。我对C语言的指针和相关内容很不熟悉。提前谢谢你!
更新
段错误是因为编译错误。如果函数要返回一个无符号字符,我在C语言中该如何声明ctypes变量呢?
1 个回答
4
不要这样传递参数,这样容易出错,而且不符合常规写法(所以看起来也不太好)。你可以直接这样做:
from ctypes import *
ibc = cdll.LoadLibrary('./libibc.so.1.0.1')
ibc.hash_id_G1.restype = c_char_p
hash = ibc.hash_id_G1(c_char_p('sometext to hash'))
除此之外,你现在遇到的问题是未定义行为,因为你返回了一个指向局部变量的指针。局部变量只在它被声明的范围内存在;在这个范围外访问它们可能会导致各种问题,从返回错误的结果到程序崩溃。如果改变编译器的选项让你的代码不再崩溃,那只是纯粹的运气。
解决这个问题的方法是,要么把你的数组声明为 static
,这样它即使在 hash_id_G1
的范围外也能继续存在...
char *hash_id_G1(char *str)
{
static char hash[20];
...
return hash;
}
...或者显式地分配内存。
char *hash_id_G1(char *str)
{
char *hash = malloc(20);
...
return hash;
}
第一个选项不是线程安全的(这可能对你的应用程序没有影响),第二个选项则需要你在之后自己 free
这块内存(或者接受一个小的内存泄漏)。
至于你新的问题,请查看文档。