Reputation: 1848
I have a C function as below :
char* hash_id_G1(char *str){
char hash[20];
...
return hash;
}
What I need is some functions like the one here, that will take in a char array and return a char array or a pointer to the char.
I will compile these into a shared so and import it into python using ctypes.
This is how I have done so far :
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)
The library does well, but I am not able to set the restype. When I do so, the code crashes with a seg fault.
I need to call the functions in the c library one by one from python. The functions generally return encryptions. How can I define these functions so that they will accept strings from the ctype interface and return the encryptions in some storable form?
Any help is appreciated. I am very weak with C pointers and related stuff. Thanks in advance
UPDATE
The segmentation fault was because of compilation error. If the function were to return an unsigned char, how would I have to declare the ctype variables in C?
Upvotes: 1
Views: 2252
Reputation: 27822
Don't pass your arguments like that; it's error-prone and not idiomatic (and therefore hard to read). You can just do the following:
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'))
Apart from that, you're dealing with undefined behaviour because you're returning a pointer to a local variable. Local variables only exist within the scope in which they were declared; accessing them outside that scope can do anything from returning bogus results to segfaulting. If changing compiler options stopped your code from segfaulting, it's only through pure luck.
The way to fix that is by either declaring your array static
, so it will persist even outside of the scope of hash_id_G1
...
char *hash_id_G1(char *str)
{
static char hash[20];
...
return hash;
}
... or to allocate memory explicitly.
char *hash_id_G1(char *str)
{
char *hash = malloc(20);
...
return hash;
}
The first option isn't thread-safe (which may not be a problem for your application), the second one requires that you free
the memory yourself afterwards (or accept a small memory leak).
As for your new question, read the documentation.
Upvotes: 4