lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On 28/09/2013 5:06 PM, Philipp Janda wrote:

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.

That's the direction I took and it works great. I snatched a version of luaL_setfuncs() from lua-cjson which done the trick.

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

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 ...

The number is a return code from the service. It can be 0, 4, 8, 12 or 20 depending on the call. I plan to write abstraction layers on top to make it more usable.

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.