[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
                              INTERFACING WITH C

    Clipper supports user-defined functions written in C through the Extend
    System.  This is a somewhat higher level interface system than the
    usual CALLs, in that you use specialized functions for both passing
    parameters to and from the routine.

    These functions reside in the Clipper library.  Your C routine must
    declare them by including EXTEND.H.  This file contains the program
    declarations and macro definitions necessary to write user-defined
    functions in C.

    C extend functions must now be defined using the CLIPPER macro or
    declaring the function "void pascal."

    Receiving Parameters in C

    The concept of C formal parameters disappears at this point. All
    parameters may be accessed using the _par() functions. Therefore, all C
    functions accessed through the Extend System are declared up with no
    formal parameters.

    Returning Values From C

    The _ret() are used to return values back to Clipper.  Each function,
    by definition, can return only one value.  The choice of which _ret()
    function you use depends on the data type being returned.

    Sample C Functions

    Once you compute the value you want to return, pass it to the
    appropriate _ret() function and it becomes the function return value.
    It is still, however, necessary to execute a C return. _ret() functions
    do not pass control back to Clipper.

    Here is a shell of a typical Clipper user defined function written in
    C:

    CLIPPER <function_name>()
    /* formal C parameters omitted */
    {
        <declarations of local variables>

        if (<parameters are valid>)
        {
                <code to execute>
        }
        else
        {
                <code to execute for undefined parameters>
                return;
        }
    }


    In Clipper:

    DECLARE arr[3]
    arr[1] = "Devorah"
    arr[2] = 456.56
    arr[3] = CTOD("09/01/87")
    Arrfunc(arr)

    In C:

    #include "extend.h"      /* Declare Extend System */
    #include "stdio.h"       /* standard io library */
    #include "math.h"        /* standard math libaray */

    CLIPPER arrfunc()        /* specify CLIPPER */
                             /* macro to define function */
    {
       int i;

       for (x = 1; x <= 3; ++x)
       {
           /* string variables */
           if (_parinfa(1, x) == CHARACTER)
           {
              cprintf("%s\n", _parc(1, x));
           }

           /* integer or floating point */
           if (_parinfa(1,X) == NUMERIC)
           {
              cprintf("%f\n", _parnd(1, x));
           }
           else
             /* dates */
             if (_parinfa(1, x) == DATE)
             {
                cprintf("%s\n", _pards(1, i));
             }
         }
     _ret();
     }

    Note: The use of cprintf() above is for demonstration purposes only.
    We recommend that all terminal I/O be done through Clipper.

    Compiling and Linking Your C Code

    To compile a Microsoft C 5.0 routine that can be MS-linked with Clipper
    Summer '87:

    CL /c /AL /Zl /Oalt /FPa /Gs <filename>.c

    where:

    CL  = the compiler command
    /c  = compile without linking
    /AL = set program configuration for (L)arge model
    /Zl = remove default (l)ibrary-search records from
          object file
    /Oalt = control optimization

    where:

    a = relax alias checking
    l = enable loop optimization
    t = favor execution speed

    /FPa  = floating point (a)lternate library
    /Gs = remove calls to (s)tack-checking routine

    Predefined C Macros

    To simplify the syntax and make the code more readable, Extend.h sets
    up several "parameter check" macros used in the if statements in
    Extendc.c for parameter checking.  The following is a table of macros
    that provide a more convenient way of parameter validation:

    #defines in Extend.h

    Type                        Returns
    -------------------------
    undefined           =       UNDEF
    character           =       CHARACTER
    numeric                     =       NUMERIC
    logical                     =       LOGICAL
    date                        =       DATE
    by reference        =       MPTR    /* or'ed with type when passed by reference */
    memo                        =       MEMO
    array                       =       ARRAY

    Predefined C Interface Macros

    EXTEND.H Macro              Defined as
    -------------------------------
    PCOUNT                              (_parinfo(0))
    ISCHAR(order)               (_parinfo(order) & CHARACTER)
    ISNUM(order)                (_parinfo(order) & NUMERIC)
    ISLOG(order)                (_parinfo(order) & LOGICAL)
    ISDATE(order)               (_parinfo(order) & DATE)
    ISMEMO(order)               (_parinfo(order) & MEMO)
    ISBYREF(order)              (_parinfo(order) & MPTR)
    ISARRAY(order)              (_parinfo(order) & ARRAY)
    ALENGTH(order)              (_parinfa(order, 0))

    Within the user-defined function, you can use the PCOUNT macro and any
    of the IS<type> macros to determine how many parameters were passed and
    their type.  This enables you to validate parameters insuring the
    correct number and type passed.  It additionally allows you to pass
    variable numbers of parameters of various types.


Reference - Extend System C Interface Functions
-----------------------------------------------

_exmback()

Free allocated memory

Syntax Usage:

#include        <extend.h>

void            *_exmback(pointer, bytes)

unsigned char   *pointer;               Pointer from _exmgrab()
unsigned int    bytes;          Size passed to _exmgrab()

Description:

_exmback() releases the memory allocated by _exmgrab().
Note that the same pointer and size used in _exmgrab must be
passed as parameters.

Example:

size = 512
buff = _exmgrab(size)           /* allocate memory */
if (buff)                                       /* if successful (!null) */
        check = TRUE;
.
.
.
if (check)
        _exmback(buff, size);           /* deallocate memory */



_exmgrab()

Allocate memory

Syntax Usage:

#include        <extend.h>

unsigned char   *_exmgrab(bytes)

unsigned int    bytes;  Requested amount of memory

Description:

_exmgrab() allocates an amount of memory in bytes.  If
successful, it returns a char pointer to the allocated space in
memory; otherwise, it returns NULL.

Example:

size = 512
buff = _exmgrab(size)           /* allocate memory */
if (buff)                                       /* if successful (!null) */
        check = TRUE;



_parc()

Passes pointer to Clipper character string

Syntax Usage:

#include        <extend.h>

char            *_parc(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_parc() is used for getting a character parameter from Clipper.
If passed by value the copy is char *.  If passed by reference,
you are acting on actual Clipper data.


_parclen()

Length of character string

Syntax Usage:

#include        <extend.h>

int             _parclen(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_parclen() returns the length of a given string.  It is used
primarily with respect to CHR(0).  This has two uses:

                Check for the length of a string with embedded
                CHR(0)s in it.

                Get the length of a string without counting the
                null terminator.



_parcsiz()

Allocated size of a character string

Syntax Usage:

#include        <extend.h>

int             _parcsiz(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_parcsiz() returns the number of bytes in memory allocated for
the specified string including the null terminator.  Note that
_parsize() returns zero for constants, e.g. DO <process> WITH
"ABC".


_pards()

Passes character pointer to Clipper date

Syntax Usage:

#include        <extend.h>

char            *_pards(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_pards() gets a date parameter from Clipper and returns a char *
in the form YYYYMMDD.  Note that there is only one _pards()
pointer on the stack and therefore you must strcopy() the result
to a variable.  You cannot simply pass the pointer.


_parinfa()

Parameter type-checking of array elements

Syntax Usage:

#include        <extend.h>

int             _parinfa(order, index)

int             order;          Placement of the array in parameter
list
int             index;          Array element index

Description:

_parinfa() returns type of an array element and is used for
parameter type-checking.  Since Clipper arrays can have mixed
type elements, each one has to be type-checked before they can
be used.  Note that _parinfa(<n>, 0) returns the number of array
elements.

Example:

The following example, arrfunc(), takes an array defined
in Clipper and displays all the elements formatted according to
data type to the console.

In Clipper:

DECLARE array[2]
array[1] = "Devorah"
array[2] = 456.56
ArrFunc(array)

In C:

for (x = 1; x <= _parinfa(1, 0); ++x)

{   /* string variables */
        if (_parinfa(1, x) == CHARACTER)
        {
                cprintf("%s\n", _parc(1, x));
        }

        /* integer or floating point */
        if (_parinfa(1, x) == NUMERIC)
        {
                cprintf("%f\n", _parnd(1, x));
        }
}



_parinfo()

Parameter type checking

Syntax Usage:

#include <extend.h>

int             _parinfo(order)

int             order;  Placement in list of
                                parameters to type-check

Description:

_parinfo() is used to test the type of a passed parameter.
_parinfo(0) returns the number of parameters passed and
_parinfo(<n>) returns the type of parameter <n> where <n> is the
position in the parameter list.  The value returned is one the
following:

/* _parinfo types from extend.h*/
#define UNDEF           0
#define CHARACTER       1
#define NUMERIC     2
#define LOGICAL     4
#define DATE            8
#define ALIAS           16
#define MPTR            32              /* or'ed with type when passed by reference */
#define MEMO            65
#define WORD            128
#define ARRAY           512

Example:

The following user-defined C function, cfunc(), recieves four
parameters from Clipper, a character type, a numeric, a logical,
and a date; defines the C variables to receive the values, then
validates the parameters:

CLIPPER cfunc()          /* no formal parameters */
{
char            *parm1;
double  parm2;
int             parm3;         /* logical is declared as int */
char            *parm4;        /* date declared as char (YYYYMMDD) */

if (PCOUNT == 4 && ISCHAR(1) && ISNUM(2) && ISLOG(3) && ISDATE(4))

        {
                <code to execute parameters valid>
        }
        else
        {
                <code to execute parameters invalid>
        }

}



_parl()

Passes Clipper logical to int

Syntax Usage:

#include        <extend.h>

int             _parl(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_parl() gets a logical parameter from Clipper and converts it to
int where (1 = .T. and 2 = .F.).



_parnd()

Passes a Clipper numeric to double

Syntax Usage:

#include        <extend.h>

double  _parnd(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_parnd() gets a numeric parameter from Clipper and converting it
to double.


_parni()

Passes Clipper numeric to int

Syntax Usage:

#include        <extend.h>

int             _parni(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_parni() gets a numeric parameter from Clipper converting it to
int.


_parnl()

Passes Clipper numeric to long

Syntax Usage:

#include        <extend.h>

long            _parnl(order, index)

int             order;  Placement in actual parameter list
int             index;  Array element index

Description:

_parnl() gets a numeric parameter from Clipper converting it to
long.



_ret()

Return to Clipper

Syntax Usage:

#include        <extend.h>

void            _ret(void)

Description:

_ret() has no Clipper return value.  This is useful so you can
execute a C function using the DO command as if it were a
Clipper procedure.


_retc()

Pass a character string to Clipper

Syntax Usage:

#include        <extend.h>

void            _retc(string)

char            *string;                Pointer to return string

Description:

_retc() returns the char* to Clipper for the character string
you want to pass back to your application program.


_retclen()

Pass the length of a string to Clipper

Syntax Usage:

#include        <extend.h>

void            _retclen(string, int)

char    *string;        Character string to return the length of
int             int;            Position in string to start the count

Description:

_retclen() returns the logical length of a string including
embedded CHR(0)s.


_retds()

Pass a date string to a Clipper date

Syntax Usage:

#include        <extend.h>

void            _retds(string)

char            *string;        Date string in the form (YYYYMMDD)

Description:

_retds() passes to Clipper as date type a char* to a string in
the form YYYYMMDD.


_retl()

Pass an int to a Clipper logical

Syntax Usage:

#include        <extend.h>

void            _retl(flag)

int             flag;           Boolean value

Description:

_retl() passes an int to Clipper as a logical value, where 1 is
true (.T.) and 0 is false (.F.).


_retnd()

Pass a double to a Clipper numeric

Syntax Usage:

#include        <extend.h>

void            _retnd(x);

double  x;              Numeric expression

Description:

_retnd() passes a double to Clipper as numeric type.



_retni()

Pass an int to a Clipper numeric

Syntax Usage:

#include        <extend.h>

void            _retni(n)

int             n;              Numeric expression

Description:

_retni() passes an int to Clipper as a numeric integer.



_retnl()

Pass a long to a Clipper numeric

Syntax Usage:

#include        <extend.h>

void            _retnl(n)

long            n;              Long numeric expression

Description:

_retnl() passes a long integer to Clipper as numeric type.

This page created by ng2html v1.05, the Norton guide to HTML conversion utility. Written by Dave Pearson