I have a problem (I think) similar to what discussed in this question:
I need to call functions contained in a rather complex plain-C shared lib:
- all functions return an
int
acting as error code (as usual0
means "all green"). - first call ever returns (in argument) an opaque pointer to an "instance".
- this pointer must be passed to all further function invocations.
In plain-C this translates to something like:
lib_instance *instance;
static lib_ConfigParameters configParams;
static const void* descriptorTable[] = { ... };
int main() {
int32_t ret;
ret = lib_getDefaultParams(&configParams);
// check ret
configParams.whatever = someParam;
ret = lib_init(&instance, &configParams, descriptorTable, sizeof(descriptorTable)/sizeof(descriptorTable[0]);
// check ret
ret = lib_somefunc(&instance, someparam);
...
}
I tried something along the lines:
from ctypes import cdll, Structure, CDLL, POINTER, c_int
class Params(Structure):
pass
lib = CDLL('../Lib/lib.so')
lib.lib_getParamDefaults.argtypes = (POINTER(Params),)
lib.lib_getParamDefaults.restype = c_int
par = Params()
ret = lib.lib_getParamDefaults(par)
print(ret, par)
but already at this level par
does not seem to contain anything useful.
I also have no idea how to handle the "instance" stuff.
Can someone point me in the right direction?
CodePudding user response:
You have two problems. First of all, you need a variable that can hold your opaque pointer. Second, you need to pass a pointer to that variable into the C function. A structure might be able to hold the opaque pointer if you defined it properly, but it seems like an over-complicated solution. There's a c_void_p
type that seems ideally suited.
I haven't tested this code but I think it does what you want.
from ctypes import cdll, CDLL, c_int, c_void_p, byref
lib = CDLL('../Lib/lib.so')
# ...
par = c_void_p()
ret = lib.lib_getParamDefaults(byref(par))
print(ret, par)