My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members

TABI is a typeful tagged cross-language calling convention

Shortly speaking, while with cdecl calling convention you pass parameters by position, TABI passes parameters by name and annotates each parameter with its type

It may be used in following situations:

  • providing interoperatbility between C, Haskell and any other languages while avoiding complexity of language-specific FFI descriptions. For example, Lua function may receive all parameters as the table
  • passing complex datastructures between various languages forth and back, providing faster alternative to serialization approach
  • implementing APIs that may be extended without losing compatibility - new services and parameters may not be supported by all client and server implementations but everything will work together

Let's see some examples. Haskell code:

-- |Client function calling server()
client = TABI.call server "service-name" ["i" ==> (1::Int), "s" ==> "str", "callback" ==> callback]

This code calls C function server() passing string and 3 named parameters: i, s, and callback. Now C code being called:

int server (char *service, TABI_ELEMENT* params)
{
	TABI_MAP p(params);
	int            i = p._int("i");               // required parameter
	char          *s = p._str("s", "");           // optional parameter with default value provided
	TABI_CALLBACK cb = p._callback("callback");   // callback function
        ...

This code extracts values of named parameters. If any required parameter is not provided, exception will be generated. Now let's call back to Haskell, using provided callback:

        ...
	cb("call it back", TABI_DYNAMAP ("n",2) ("name","Bulat"));
	return 0;
}

Again, we pass to Haskell function one string and two named parameters: n and name. Now let's look at this function:

-- |Function called back from server()
callback service p = do
  n       <- TABI.required p "n"
  name    <- TABI.optional p "name"    "-"
  missing <- TABI.optional p "missing" "-"
  print (service, n::Int, name::String, missing::String)
  return 0

So, we have demonstrated how to call from Haskell to C and from C to Haskell using TABI.

Powered by Google Project Hosting