Types available by default in CInterface
might not be enough for your needs. Also, sometimes you might
need to change sliglty the behavior of existing types. In that sort of cases, you will need to
know more about what is going on under the hood.
When you do a call to wrap(),
interface:wrap(
"numel", -- the Lua name
"numel", -- the C function name, here the same
-- now we describe the 'arguments' of the C function
-- (or possible returned values)
{
{name="DoubleTensor"},
{name="int", creturned=true} -- this one is returned by the C function
}
)
the method will examine each argument you provide. For example, let's consider:
{name="int", creturned=true}
Considering the argument field name
, wrap will check if the field
interface.argtypes['int']
exists or not. If it does not exist, an error will be raised.
In order to describe what happens next, we will now denote
arg = {name="int", creturned=true}
First thing which is done is assigning interface.argtypes['int']
as a metatable to arg
:
setmetatable(arg, interface.argtypes[arg.name])
Then, a number of fields are populated in arg
by wrap:
arg.i = 2 -- argument index (in the argument list) in the wrap() call
arg.__metatable = interface.argtypes[arg.name]
arg.args = ... -- the full list of arguments given in the wrap() call
wrap() will then call a several methods which are
assumed to be present in arg
(see below for the list). Obviously, in
most cases, methods will be found in the metatable of arg
, that is in
interface.argtypes[arg.name]
. However, if you need to override a method
behavior for one particular argument, this method could be defined in the
table describing the argument, when calling wrap().
The extra fields mentionned above (populated by wrap) can be used in the argument methods to suit your needs (they are enough to handle most complex cases).
We will now describe methods which must be defined for each type. We will
take as example boolean
, to make things more clear. If you want to see
more complex examples, you can have a look into the types.lua
file,
provided by the wrap package.
Returns a string describing (in a human readable fashion) the name of the given arg.
Example:
function helpname(arg)
return "boolean"
end
Returns a C code string declaring the given arg.
Example:
function declare(arg)
return string.format("int arg%d = 0;", arg.i)
end
Returns a C code string checking if the value at index idx
on the Lua stack
corresponds to the argument type. The string will appended in a if()
, so it should
not contain a final ;
.
Example:
function check(arg, idx)
return string.format("lua_isboolean(L, %d)", idx)
end
Returns a C code string converting the value a index idx
on the Lua stack, into
the desired argument. This method will be called only if the C check given by
check() succeeded.
Example:
function read(arg, idx)
return string.format("arg%d = lua_toboolean(L, %d);", arg.i, idx)
end
Returns a C code string initializing the argument by its default
value. This method will be called only if (1) arg
has a default
field and (2) the C check given by check()
failed (so the C code in read() was not called).
Example:
function init(arg)
local default
if arg.default then
default = 1
else
default = 0
end
return string.format("arg%d = %s;", arg.i, default)
end
Returns a C code string describing how to pass
the given arg
as argument when calling the C function.
In general, it is just the C arg name itself (except if you need to pass the argument "by address", for example).
Example:
function carg(arg)
return string.format('arg%d', arg.i)
end
Returns a C code string describing how get the argument if it is returned from the C function.
In general, it is just the C arg name itself (except if you need to assign a pointer value, for example).
function creturn(arg)
return string.format('arg%d', arg.i)
end
Returns a C code string if you need to execute specific code related to
arg
, before calling the C function.
For e.g., if you created an object in the calls before, you might want to put it on the Lua stack here, such that it is garbage collected by Lua, in case the C function call fails.
function precall(arg)
-- nothing to do here, for boolean
end
Returns a C code string if you need to execute specific code related to
arg
, after calling the C function. You can for e.g. push the argument
on the stack, if needed.
function postcall(arg)
if arg.creturned or arg.returned then
return string.format('lua_pushboolean(L, arg%d);', arg.i)
end
end