Welcome to mirror list, hosted at ThFree Co, Russian Federation.

index.dok « dok - github.com/torch/cwrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 422c6066009e0fb916a050f3ad6cc1cffff5aba4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
====== Wrap package ======

The **wrap** package helps you to automate the generation of Lua/C wrappers
around existing C functions, such that these functions would be callable
from Lua. This package is used by the **torch** package, but does not depend on
anything, and could be used by anyone using Lua.

**DISCLAIMER** Before going any further, we assume the reader has a good
knowledge of how to interface C functions with Lua. A good start would be
the [[http://www.lua.org/manual/5.1|Lua reference manual]], or the book
[[http://www.inf.puc-rio.br/~roberto/pil2|Programming in Lua]].

As an example is often better than lengthy explanations, let's consider the
case of a function
<file c>
int numel(THDoubleTensor *t);
</file>
which returns the number of elements of ''t''.
Writing a complete wrapper of this function would look like:
<file c>
int wrapper_numel(lua_State *L)
{
  THDoubleTensor *t;

  /* always good to check the number of arguments */
  if(lua_gettop(L) != 1)
    error("invalid number of arguments: <tensor> expected");

  /* check if we have a tensor on the stack */
  /* we use the luaT library, which deals with Torch objects */
  /* we assume the torch_DoubleTensor_id has been already initialized */
  t = luaT_checkudata(L, 1, torch_DoubleTensor_id);

  /* push result on stack */
  lua_pushnumber(L, numel(t));

  /* the number of returned variables */
  return 1;
}
</file>

For anybody familiar with the Lua C API, this should look very simple (and
//it is simple//, Lua has been designed for that!). Nevertheless, the
wrapper contains about 7 lines of C code, for a quite simple
function. Writing wrappers for C functions with multiple arguments, where
some of them might be optional, can become very quickly a tedious task. The
**wrap** package is here to help the process. Remember however that even
though you might be able to treat most complex cases with **wrap**,
sometimes it is also good to do everything by hand yourself!

===== High Level Interface =====

**wrap** provides only one class: ''CInterface''. Considering our easy example, a typical usage
would be:
'
<file lua>
require 'wrap'

interface = wrap.CInterface.new()

interface:wrap(
   "numel", -- the Lua name
   "numel", -- the C function name, here the same
   -- now we describe the 'arguments' (or possibly returned values)
   {
      {name="DoubleTensor"},
      {name="int", creturned=true} -- this one is returned by the C function
   }
)

print(interface:tostring())
</file>
The wrapper generated by **wrap** is quite similar to what one would write by hand:
<file c>
static int wrapper_numel(lua_State *L)
{
  int narg = lua_gettop(L);
  THDoubleTensor *arg1 = NULL;
  int arg2 = 0;
  if(narg == 1
     && (arg1 = luaT_toudata(L, 1, torch_DoubleTensor_id))
    )
  {
  }
  else
    luaL_error(L, "expected arguments: DoubleTensor");
  arg2 = numel(arg1);
  lua_pushnumber(L, (lua_Number)arg2);
  return 1;
}
</file>