> That is, instead of > devhandle->enumerate_children(dev, devhandle, callback, callback_arg)
> (which one might dress up with a macro), we get, equally unwrapped: > struct device_enumerate_children_args args; > args.callback = callback; > args.callback = callback_arg; > call = devhandle->lookup_device_call(devhandle, "string", &handle2); > call(dev, handle2, &args); > [W]hat purpose does this level of indirection serve? Looking at the > implementation, it sure seems like "none at all". It occurs to me that one thing it does do is fairly effectively insulate callers against possible changes to the list of supported methods, what in your first example would be the struct holding the method implementation pointers. This makes for slightly better binary compatability in the presence of version mismatches. (It does _not_ insulate against changes to the argument patterns passed to those methods, what in your first example would be the signature of the method function and in the second example would be the definition of the args struct.) Is that the purpose of it? I don't know. But it certainly is one of the effects of it. Is it worth losing the other benefits of the former way? That's a good question. At the moment, my inclination is to come down in favour of the typechecked interface. But that's just one opinion, and a relatively uninformed one at that. /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B