|
Hi! Am 27.09.2013 14:50 schröbte David Crayford:
// ISPF API functions. typedef int (isplink_t)(); typedef int (ispexec_t)( size_t, const char * ); struct ISPF_services { isplink_t * isplink; ispexec_t * ispexec; } api; // load ISPLINK/ISPEXEC services api.isplink = ( isplink_t * ) fetch("ISPLINK"); api.ispexec = ( ispexec_t * ) fetch("ISPEXEC");
Can you call `fetch("ISPLINK")` multiple times? Do you need to unregister those services (once, or for every fetch call)? Is `api` really a global, or is this sample code?
Is it better to return the API as userdata or create a table? I'm a neophyte so bear with me.
Lua cannot represent or use a generic function pointer on the Lua side (other than as a void pointer), so there *will* be a userdata involved anyway. I'd go for a single full userdata storing the api struct (or a pointer to it if api is a global variable) and a metatable + __index-table for the methods. In your special case you could also create your methods as closures which store the userdata as an upvalue, and return a table containing those closuses. As a consequence you could (but wouldn't need to) use the alternative syntax `ispf.exec("DISPLAY PANEL(P)")`, and you could omit some type checking inside the methods. And number three is: Wrap each function pointer in a separate userdata (inside a struct to be ANSI C compatible) and set the __call metamethod. You could return a table having an __index function to load your services on-demand ...
I want to be able to do something like this ispf = require("ispf") while ispf:exec("DISPLAY PANEL(P)") == 0 do -- process the panel end
This is pretty standard stuff (with the possible exception that your module seems to be some sort of singleton), but maybe you want your `exec` function to return a boolean (+ additional return values) instead of a number ... And relying on `require` to only load your module once is not safe! If someone resets `package.loaded.ispf`, and `require`s your module again, your module will be loaded a second time.
HTH, Philipp