Difference between revisions of "Low-level API for Writing Extensions in GrADS v2.0"
(no need for DLL ext) |
|||
Line 9: | Line 9: | ||
# Type API Name Function Library | # Type API Name Function Library | ||
# ------ --- --------------- ---------------- --------------------------- | # ------ --- --------------- ---------------- --------------------------- | ||
− | udf 0 hello f_hello ^hello.gex | + | udf 0 hello f_hello ^hello.gex |
The <tt>Name</tt> (''hello'' in this example) is the name of the function to be used in a GrADS expression; <tt>Function</tt> is the name of the C-function (''f_hello'' in this case) inside the dynamically linked library (DLL) <tt>Library</tt>. The <tt>API</tt> version (''0'' in this example) is used to denote a particular version of the UDF API, allowing for future extensions. | The <tt>Name</tt> (''hello'' in this example) is the name of the function to be used in a GrADS expression; <tt>Function</tt> is the name of the C-function (''f_hello'' in this case) inside the dynamically linked library (DLL) <tt>Library</tt>. The <tt>API</tt> version (''0'' in this example) is used to denote a particular version of the UDF API, allowing for future extensions. | ||
− | The optional caret ('''^''') in this example is useful to simplify installation: it tells GrADS that the DLL is found at the same directory where ''User Defined Extension'' table is located, freeing the user from having to set environment variables such as <tt>LD_LIBRARY_PATH</tt> | + | The optional caret ('''^''') in this example is useful to simplify installation: it tells GrADS that the DLL is found at the same directory where ''User Defined Extension'' table is located, freeing the user from having to set environment variables such as <tt>LD_LIBRARY_PATH</tt>. |
==Example: Hello World== | ==Example: Hello World== |
Revision as of 07:09, 19 January 2012
The OpenGrADS User Defined Extensions in GrADS v1.9.0-rc1 was implemented in terms of the low-level GrADS data structures. While such approach provided maximum flexibility in so far as to provided access to all GrADS internals, it was a very fragile and tied to a particular version of GrADS. An internal in data structure, even if it did not require changes in the extension source code, it very often required re-compilation. Therefore, this is not a recommended interface for developing new User Defined Extensions.
For each User Defined Function (UDF), the user provides a C function with a standard interface:
#include "grads.h" int f_hello (struct gafunc *pfc, struct gastat *pst);
where grads.h is the main GrADS include file. The data structures gafunc and gastat are the same structures used to implement GrADS intrinsic functions. In fact, a UDF implemented this way can be easily implemented as a GrADS intrinsic function. In addition, for each UDF, the user provides an entry in a User Defined Extension" (UDX) table which tells GrADS where to look for the UDF.
# Type API Name Function Library # ------ --- --------------- ---------------- --------------------------- udf 0 hello f_hello ^hello.gex
The Name (hello in this example) is the name of the function to be used in a GrADS expression; Function is the name of the C-function (f_hello in this case) inside the dynamically linked library (DLL) Library. The API version (0 in this example) is used to denote a particular version of the UDF API, allowing for future extensions.
The optional caret (^) in this example is useful to simplify installation: it tells GrADS that the DLL is found at the same directory where User Defined Extension table is located, freeing the user from having to set environment variables such as LD_LIBRARY_PATH.
Example: Hello World
Here is the full source code for the Hello World! extension:
#include <stdio.h> #include "grads.h" static counter = 0; /* Illustrates how to keep a state */
/* Sample Hello, World! user defined command */ int c_hello ( int argc, char **argv, struct gacmn *pcm) { int i; counter++; printf("[%d] Hello, GrADS v2.0 World! \n", counter); for (i=0; i<argc; i++) printf(" argv[%d] = <%s>\n", i, argv[i]); return 0; }
/* Sample Hello, World! user defined function */ int f_hello (struct gafunc *pfc, struct gastat *pst) { int rc; counter++; printf("[%d] Hello, GrADS v2.0 World!\n", counter); rc = gaexpr("0",pst); /* return a zero grid */ return (rc); }