免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7969 | 回复: 3
打印 上一主题 下一主题

[函数] [开发现场求助]==C调用4gl函数的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-10-23 18:36 |只看该作者 |倒序浏览
目的:在C语言的主程序中调用一个4GL的函数

问题:现在已经可以实现C语言的程序的参数传入4GL的函数,函数执行也已经完成,但是在我接收从4GL的程序中返回的参数的时候确出了CORE

程序:4gl函数

  1. function fgl_test( poli, trandate )
  2. define poli char(17)
  3. define trandate date
  4. define prem decimal(8,2)
  5.     display 'test succeed'
  6.         display "poli=",poli
  7.         display "trandate=",poli
  8.         let prem = 1000.00
  9.         return prem
  10.         display "prem", prem
  11. end function
复制代码


C主程序:
  1. #include <fglapi.h>;
  2. #include <fglsys.h>;
  3. #include <stdio.h>;

  4. main()
  5. {

  6.         char pszPoli[80];
  7.         long lDate;
  8.         double dTmp = 0;
  9.         int iRet;
  10.        
  11.         memset( pszPoli, 0, sizeof(pszPoli) );
  12.         memcpy( pszPoli, "3211020017000003", 16 );
  13.         iRet = rdefmtdate( &lDate, "yyyymmdd", "20041023" );
  14.         if ( iRet < 0 ) {
  15.        
  16.             printf( "交易日期转换出错 : [%d]", iRet );
  17.         }
  18.                
  19.         fgl_start( "example" );
  20.         pushdate( lDate );
  21.         pushquote( pszPoli, strlen(pszPoli) );
  22.        
  23.         printf( "---------------" );
  24.         fgl_call(fgl_test, 2);       
  25.         printf( "---------------" );
  26.        
  27.         popdec( dTmp );
  28.         printf("dTmp : [%f]\n", dTmp);
  29.         fgl_end();

  30.         printf( "-------------\n" );
  31.         return 0;

  32. }
复制代码


错误:popdec( dTmp );因该就是这个函数报错

希望广大兄弟帮忙,开发现场急救,谢谢各位





附:参考资料

Some programming tasks might be more easily or more
efficiently coded with a combination of IBM Informix 4GL code
and C code. In these cases, you have two options:
 Write a 4GL program that calls C functions.
 Write a C program that calls 4GL functions.
To call either a C function or a 4GL function, you must know
about the argument stack mechanism (discussed in “Using the
Argument Stack” on page C-5) that 4GL uses to pass arguments
between the functions and the calling code. This appendix
discusses issues that relate to the application programming
interface (API) between the 4GL language and the C language:
 Calling a C function from a 4GL program
The CALL statement of 4GL can invoke C functions that
observe the calling conventions of the 4GL argument
stack (as described in “Calling a C Function from a 4GL
Program” on page C-15).
 Calling a 4GL function from a C program
For a C program to call a 4GL function, it must include a
special header file. 4GL provides macros to initialize the
argument stack and to support other requirements of the
C language (as described in “Macros for Calling 4GL
Functions” on page C-24).
 Decimal functions for C
4GL provides a library of functions that facilitate the conversion
of its own DECIMAL data type values to and
from every data type of the C language (as described in
“Decimal Functions for C” on page C-2.
C-2 IBM Informix 4GL Reference Manual
 DYNAMIC ARRAY functions for C
The DYNAMIC ARRAY data type is a 4GL-specific machine-independent
data structure for storing large numbers of similar values in
memory. 4GL provides a library of functions that process DYNAMIC
ARRAY (as described in “Dynamic Array Functions for C” on
page C-42).
 BIGINT functions for C
4GL provides a library of functions that facilitates the conversion of
its own BIGINT data type values to and from other data types in the
C language (as described in “BIGINT Functions for C” on
page C-49.)
The following topics are described in this appendix.
Topic Page
Using the Argument Stack C-5
Passing Values Between 4GL Functions C-5
Receiving Values from 4GL C-7
Passing Values to 4GL C-11
Calling a C Function from a 4GL Program C-15
Compiling and Executing the Program C-18
Calling a 4GL Function from a C Program C-18
Including the fglapi.h File C-19
Initializing the Argument Stack C-19
Invoking the 4GL Function C-20
Using Interrupt Signals C-22
Compiling and Executing the C Program C-22
Macros for Calling 4GL Functions C-24
fgl_start( ) C-24
fgl_call( ) C-25
(1 of 3)
Using C with IBM Informix 4GL C-3
fgl_exitfm( ) C-26
fgl_end( ) C-27
Decimal Functions for C C-28
deccvasc( ) C-30
dectoasc( ) C-32
deccvint( ) C-33
dectoint( ) C-34
deccvlong( ) C-35
dectolong( ) C-35
deccvflt( ) C-36
dectoflt( ) C-37
deccvdbl( ) C-38
dectodbl( ) C-38
decadd( ), decsub( ), decmul( ), and decdiv( ) C-39
deccmp( ) C-40
deccopy( ) C-41
dececvt( ) and decfcvt( ) C-41
Dynamic Array Functions for C C-42
ibm_lib4gl_allocateDA( ) C-44
ibm_lib4gl_deallocateDA( ) C-44
ibm_lib4gl_getDataAddressDA( ) C-45
ibm_lib4gl_getDataSizeDA( ) C-46
ibm_lib4gl_getExtentSizeDA( ) C-46
ibm_lib4gl_isAllocatedDA( ) C-47
Topic Page
(2 of 3)
C-4 IBM Informix 4GL Reference Manual
The sections that describe these functions also contain code examples.
ibm_lib4gl_resizeDA( ) C-48
BIGINT Functions for C C-49
ifx_int8add( ) C-51
ifx_int8cmp( ) C-51
ifx_int8copy( ) C-52
ifx_int8cvasc( ) C-53
ifx_int8cvdbl( ) C-54
ifx_int8cvdec( ) C-54
ifx_int8cvflt( ) C-55
ifx_int8cvint( ) C-56
ifx_int8cvlong( ) C-56
ifx_int8cvlong_long( ) C-57
ifx_int8div( ) C-58
ifx_int8mul( ) C-58
ifx_int8sub( ) C-59
ifx_int8toasc( ) C-60
ifx_int8todbl( ) C-61
ifx_int8todec( ) C-61
ifx_int8toflt( ) C-62
ifx_int8toint( ) C-63
ifx_int8tolong( ) C-64
ifx_int8tolong_long( ) C-64
Topic Page
(3 of 3)
Using C with IBM Informix 4GL C-5
Using the Argument Stack
Using the Argument Stack
Within a 4GL program, 4GL uses a pushdown stack to pass arguments and
results between 4GL functions. The caller of a function pushes its arguments
onto the stack; the called function pops them off the stack to use the values.
The called function pushes its return values onto the stack, and the caller
pops them off to retrieve the values.The argument stack is also used when a
4GL program calls a C function that you have written or when a C program
calls a 4GL function. This section describes the following operations:
 Passing values between 4GL functions
 Receiving values from 4GL
 Passing values to 4GL
C code that calls any of the library functions that push, pop, or return values
in the pushdown stack should include the file fglsys.h at the top of the file:
#include <fglsys.h>;
Passing Values Between 4GL Functions
Consider the following 4GL program:
MAIN
DEFINE j,k,sum,dif SMALLINT
LET j=5
LET k=7
CALL sumdiff(j,k) RETURNING sum, dif
END MAIN
FUNCTION sumdiff(a,b)
DEFINE a,b,s,d DECIMAL(16)
LET s = a+b
LET d = a-b
RETURN s,d
END FUNCTION
When the program executes the CALL statement, 4GL first notes the current
argument stack depth. Then it pushes the function arguments onto the top of
the stack in sequence from left to right (first j and then k in the example). The
stack receives not only the value of an argument but its data type as well
(SMALLINT in the example).
C-6 IBM Informix 4GL Reference Manual
Passing Values Between 4GL Functions
The called function pops the arguments off the stack into local variables
(a and b, respectively). In the example, the types of these variables
(DECIMAL) are different from the types of the arguments that were pushed
by the caller (SMALLINT). However, because the stack stores the type of each
passed value, 4GL is able to convert the arguments to the proper type. In this
instance, 4GL easily converts SMALLINT values to DECIMAL. Any type
conversion that is supported by the LET statement is supported when
popping stacked values.
The RETURN statement pushes the returned values onto the stack in sequence
from left to right (first s and then d in the example). The RETURNING clause
in the originating CALL statement then pops these values off the stack and
into the specified variables (sum and diff, respectively) and converts the data
types DECIMAL back to SMALLINT.
When 4GL calls a function within an expression, the use of the stack is the
same as in the CALL statement. The function is expected to return a single
value on the stack, and 4GL attempts to convert this value as required to
evaluate the expression.
Important: Releases of 4GL earlier than Version 7.31 provided function libraries that
used different function names. For details, see the fglsys.h file, included in 4GL. To
consistently maintain differences on 32-bit and 64-bit platforms, 4GL 7.31 introduced
new mappings for C data types. These new data types should be used when calling
any 4GL library. For more details of the mapping between the new data types and Cdefined
variables, see the fgltypes.h file, included in 4GL.
Function prototypes in the sections that follow use the Version 7.31 function
names. The corresponding pre-Version 7.31 function names are shown with
Version 7.31 function prototypes.
Important: If you are compiling C programs with your 4GL program based on the
pre-Version 7.31 functions for manipulating the 4GL function stack, in order to get
the correct mappings from the old functions names to the new functions names, you
must include fglsys.h as the header file in the C program.
Using C with IBM Informix 4GL C-7
Receiving Values from 4GL
Receiving Values from 4GL
C functions or programs receive arguments from 4GL by using the argument
stack. Within the C function or program, you pop values off the stack by
using pop external functions that are included with 4GL. If you try to pop a
value when none is on the stack, a core dump or other fatal behavior can
occur.
This section describes the pop external functions, according to the data type
of the value that each pops from the argument stack.
Library Functions for Popping Numbers
You can call the following 4GL library functions from a C function or program
to pop number values from the argument stack:
extern void ibm_lib4gl_popMInt(mint *iv)
extern void ibm_lib4gl_popInt2(int2 *siv)
extern void ibm_lib4gl_popInt4(int4 *liv)
extern void ibm_lib4gl_popFloat(float *fv)
extern void ibm_lib4gl_popDouble(double *dfv)
extern void ibm_lib4gl_popDecimal(dec_t *decv)
extern void ibm_lib4gl_popInt8(ifx_int8_8t *bi)
extern void ibm_lib4gl_popDA(int4 *array_descriptor)
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
Pre-7.31 Version Name 7.31 Version Name
popint ibm_lib4gl_popMInt
popshort ibm_lib4gl_popInt2
poplong ibm_lib4gl_popInt4
popflo ibm_lib4gl_popFloat
popdub ibm_lib4gl_popDouble
popdec ibm_lib4gl_popDecimal
C-8 IBM Informix 4GL Reference Manual
Receiving Values from 4GL
Each of these functions, like all library functions for popping values,
performs the following actions:
1. Removes one value from the argument stack
2. Converts its data type if necessary. If the value on the stack cannot be
converted to the specified type, the result is undefined.
3. Copies it to the designated variable
Important: The extern void ibm_lib4gl_popDA(int4 *array_descriptor)
function does not convert data type values. In addition, the value popped from the
stack must be a dynamic array value, or else you will receive an error. All the C
functions working with the dynamic array data type should operate on an array
descriptor returned by this function.
The dec_t structure referred to by ibm_lib4gl_popDecimal( ) is used to hold
a DECIMAL value. It is discussed later in this appendix.
The ifx_int8_t structure referred to by ibm_lib4gl_popInt8( ) is used to hold
a BIGINT value. It is discussed later in this appendix.
Library Functions for Popping Character Strings
You can call the following 4GL library functions to pop character values:
extern void ibm_lib4gl_popQuotedStr(int1 *qv, mint len)
extern void ibm_lib4gl_popString(int1 *qv, mint len)
extern void ibm_lib4gl_popVarChar(int1 *qv, mint len)
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
Pre-7.31 Version Name 7.31 Version Name
popquote ibm_lib4gl_popQuotedStr
popstring ibm_lib4gl_popString
popvchar ibm_lib4gl_popVarChar
Using C with IBM Informix 4GL C-9
Receiving Values from 4GL
Both ibm_lib4gl_popQuotedStr( ) and ibm_lib4gl_popVarChar( ) copy
exactly len bytes into the string buffer *qv. Here
ibm_lib4gl_popQuotedStr( ) pads with spaces as necessary, but
ibm_lib4gl_popVarChar( ) does not pad to the full length. The final byte
copied to the buffer is a null byte to terminate the string, so the maximum
string data length is len-1. If the stacked argument is longer than len-1, its
trailing bytes are lost.
The len argument sets the maximum size of the receiving string buffer.Using
ibm_lib4gl_popQuotedStr( ), you receive exactly len bytes (including
trailing blank spaces and the null), even if the value on the stack is an empty
string. To find the true data length of a string retrieved by
ibm_lib4gl_popQuotedStr( ), you must trim trailing spaces from the
popped value. (The functions ibm_lib4gl_popString( ) and
ibm_lib4gl_popQuotedStr( ) are identical, except that
ibm_lib4gl_popString( ) automatically trims any trailing blanks.)
Because 4GL can convert values to CHAR from any data type except TEXT or
BYTE, you can use these functions to pop almost any argument.
Library Functions for Popping Time Values
You can call the following 4GL library functions to pop DATE, DATETIME, and
INTERVAL values:
extern void ibm_lib4gl_popDate(int4 *datv)
extern void ibm_lib4gl_popDateTime(dtime_t *dtv, mint qual)
extern void ibm_lib4gl_popInterval(intrvl_t *iv, mint qual)
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
Pre-7.31 Version Name 7.31 Version Name
popdate ibm_lib4gl_popDate
popdtime ibm_lib4gl_popDateTime
popinv ibm_lib4gl_popInterval
C-10 IBM Informix 4GL Reference Manual
Receiving Values from 4GL
The structure types dtime_t and intrvl_t are used to represent DATETIME and
INTERVAL data in a C program. They are discussed in the IBM Informix
ESQL/C Programmer’s Manual. The qual argument receives the binary representation
of the DATETIME or INTERVAL qualifier. The IBM Informix ESQL/C
Programmer’s Manual also discusses library functions for manipulating and
printing DATE, DATETIME, and INTERVAL variables.
Library Functions for Popping BYTE or TEXT Values
You can call the following function to pop a BYTE or TEXT argument:
extern void ibm_lib4gl_popBlobLocator(loc_t **blob)
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
The structure type loc_t defines a BYTE or TEXT value. Its use is discussed in
your Administrator’s Guide. The ibm_lib4gl_popBlobLocator( ) function is
unusual in that it does not copy the passed value. The function copies only
the address of the passed value (as is indicated by the double asterisk in the
function prototype). The following C fragment illustrates this:
mint get_a_text(mint nargs)
{
loc_t *theText;
ibm_lib4gl_popBlobLocator(&theText)
...
}
What ibm_lib4gl_popBlobLocator( ) stores at the address specified by its
parameter is the address of the locator structure owned by the calling
function. A change to the locator or the value that it describes is visible to the
calling program, which is not the case with other data types.
Any BYTE or TEXT argument must be popped as BYTE or TEXT because 4GL
provides no automatic data type conversion.
Pre-7.31 Version Name 7.31 Version Name
poplocator ibm_lib4gl_popBlobLocator
Using C with IBM Informix 4GL C-11
Passing Values to 4GL
Passing Values to 4GL
C functions or programs can pass one or more arguments to 4GL by putting
the arguments on the stack:
 When returning values to a 4GL program from a C function, you use
the external return functions that are provided with 4GL to put the
arguments on the stack.
 When passing values to a 4GL function from a C program, you use
the external push functions that are provided with 4GL to put the
arguments on the stack.
The external return functions copy their arguments to storage allocated
outside the calling function. This storage is released when the returned value
is popped. This situation makes it possible to return values from local
variables of the function.
The external push functions do not make a copy of the pushed data value in
allocated memory. They require a pushed value to be a variable that will be
valid for the duration of the call. It is up to the calling code to dispose of the
values, as necessary, after the call. Sections that follow describe the external
return and push functions.
Important: The dynamic array variable type cannot be declared in a C program, and
you cannot pass a dynamic array value to a 4GL function or program from a C
function or program. The dynamic array data type is a 4GL language-specific data
structure, and is stored internally in a dynamic array stack table.
The Return Library Functions
The following 4GL library functions are available to return values:
extern void ibm_lib4gl_returnMInt(mint iv)
extern void ibm_lib4gl_returnInt2(int2 siv)
extern void ibm_lib4gl_returnInt4(int4 lv)
extern void ibm_lib4gl_returnFloat(float *fv)
extern void ibm_lib4gl_returnDouble(double *dfv)
extern void ibm_lib4gl_returnDecimal(dec_t *decv)
extern void ibm_lib4gl_returnQuotedStr(int1 *str0)
extern void ibm_lib4gl_returnString(int1 *str0)
extern void ibm_lib4gl_returnVarChar(int1 *vc)
extern void ibm_lib4gl_returnDate(int4 date)
C-12 IBM Informix 4GL Reference Manual
Passing Values to 4GL
extern void ibm_lib4gl_returnDateTime(dtime_t *dtv)
extern void ibm_lib4gl_returnInterval(intrvl_t *inv)
extern void ibm_lib4gl_returnInt8(ifx_int8_t *bi)
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
The argument of ibm_lib4gl_returnQuotedStr( ) is a null-terminated string.
The ibm_lib4gl_returnString( ) function is included only for symmetry; it
internally calls ibm_lib4gl_returnQuotedStr( ).
No library function is available for returning BYTE or TEXT values, which are
passed by reference.
The C function can return data in whatever form is convenient. If conversion
is possible, 4GL converts the data type as required when popping the value.
If data type conversion is not possible, an error occurs.
Pre-7.31 Version Name 7.31 Version Name
retint ibm_lib4gl_returnMInt
retshort ibm_lib4gl_returnInt2
retlong ibm_lib4gl_returnInt4
retflo ibm_lib4gl_returnFloat
retdub ibm_lib4gl_returnDouble
retdec ibm_lib4gl_returnDecimal
retquote ibm_lib4gl_returnQuotedStr
retstring ibm_lib4gl_returnString
retvchar ibm_lib4gl_returnVarChar
retdate ibm_lib4gl_returnDate
retdtime ibm_lib4gl_returnDateTime
retinv ibm_lib4gl_returnInterval
Using C with IBM Informix 4GL C-13
Passing Values to 4GL
C functions called from 4GL must always exit with the statement return(n),
where n is the number of return values pushed onto the stack.Afunction that
returns nothing must exit with return(0).
The Push Library Functions
You can use the following 4GL library functions to push number values:
extern void ibm_lib4gl_pushMInt(mint iv)
extern void ibm_lib4gl_pushInt2(int2 siv)
extern void ibm_lib4gl_pushInt4(int4 liv)
extern void ibm_lib4gl_pushFloat(float *fv)
extern void ibm_lib4gl_pushDouble(double *dfv)
extern void ibm_lib4gl_pushDecimal(dec_t *decv, unsigned decp)
extern void ibm_lib4gl_pushInt8(ifx_int8_t *bi)
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
The dec_t structure type and the C functions for manipulating decimal data
are discussed later in this appendix. The second argument of
ibm_lib4gl_pushDecimal( ), namely decp, specifies the decimal precision
and scale.
For example, to give a decimal variable named dec_var the precision of 15
and the scale of 2, you could specify the following values:
ibm_lib4gl_pushDecimal(dec_var, PRECMAKE(15,2));
Here PRECMAKE is a macro defined in the decimal.h file.
Pre-7.31 Version Name 7.31 Version Name
pushint ibm_lib4gl_pushMInt
pushshort ibm_lib4gl_pushInt2
pushlong ibm_lib4gl_pushInt4
pushflo ibm_lib4gl_pushFloat
pushdub ibm_lib4gl_pushDouble
pushdec ibm_lib4gl_pushDecimal
C-14 IBM Informix 4GL Reference Manual
Passing Values to 4GL
You can use the following library functions to push character values:
extern void ibm_lib4gl_pushQuotedStr(int1 *cv, mint len)
extern void ibm_lib4gl_pushVarChar(int1 *vcv, mint len)
The ifx_int8_t structure and the C functions for manipulating or converting
the data contained therein are discussed later in this appendix.
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
The arguments to ibm_lib4gl_pushQuotedStr( ) and
ibm_lib4gl_pushVarChar( ) are an unterminated character string and the
count of characters that it contains (not including any null terminator).
You can use the following library functions to push DATE, DATETIME, and
INTERVAL values:
extern void ibm_lib4gl_pushDate(int4 datv)
extern void ibm_lib4gl_pushDateTime(dtime_t *dtv)
extern void ibm_lib4gl_pushInterval(intrvl_t *inv)
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
This library function pushes the location of a TEXT or BYTE argument:
extern void ibm_lib4gl_pushBlobLocator(loc_t *blob)
Pre-7.31 Version Name 7.31 Version Name
pushquote ibm_lib4gl_pushQuotedStr
pushvchar ibm_lib4gl_pushVarChar
Pre-7.31 Version Name 7.31 Version Name
pushdate ibm_lib4gl_pushDate
pushdtime ibm_lib4gl_pushDateTime
pushinv ibm_lib4gl_pushInterval
Using C with IBM Informix 4GL C-15
Calling a C Function from a 4GL Program
The correspondence between pre-Version 7.31 and Version 7.31 function
names follows.
Calling a C Function from a 4GL Program
To call a C function from a 4GL program, use the CALL statement and specify
the following information:
 The name of the C function
 Any arguments to pass to the C function
 Any variables to return to the 4GL program
Important: To run or debug a 4GL Rapid Development System program that calls C
functions, you must first create a customized runner. For a complete description of
this process, refer to “Creating a Customized Runner” on page 1-85.
For example, the following CALL statement calls the C function sendmsg( ).
It passes two arguments (chartype and 4, respectively) to the function and
expects two arguments to be passed back (msg_status and return_code,
respectively):
CALL sendmsg(chartype, 4) RETURNING msg_status, return_code
The C function receives an integer argument that specifies how many values
were pushed on the argument stack (in this case, two arguments). This is the
number of values to be popped off the stack in the C function. The function
also needs to return values for the msg_status and return_code arguments
before passing control back to the 4GL program.
Pre-7.31 Version Name 7.31 Version Name
pushlocator ibm_lib4gl_pushBlobLocator
C-16 IBM Informix 4GL Reference Manual
Calling a C Function from a 4GL Program
The C function should not assume it has been passed the correct number of
stacked values. The C function should test its integer argument to see how
many 4GL arguments were stacked for it. (If a function is called from two or
more statements in the same source module, 4GL verifies that the same
number of arguments is used in each call. A function could be called,
however, from different source modules, with a different number of
arguments from each module. This error, if it is an error, is not caught by 4GL.)
This example shows a C function that requires exactly one argument:
#include <fglsys.h>;
#include <fgltypes.h>;
...
...
mint nxt_bus_day(mint nargs);
{
int4 theDate;
if (nargs != 1)
{
fprintf(stderr,
"nxt_bus_day: wrong number of parms (%d)\n",
nargs );
ibm_lib4gl_returnDate(0L);
return(1);
}
ibm_lib4gl_popDate(&theDate);
switch(rdayofweek(theDate))
{
case 5: /* change friday ->; monday */
++theDate;
case 6: /* saturday ->; monday*/
++theDate;
default: /* (sun..thur) go to next day */
++theDate;
}
ibm_lib4gl_returnDate(theDate); /* stack result */
return(1) /* return count of stacked */
}
The function returns the date of the next business day after a given date.
Because the function must receive exactly one argument, the function checks
for the number of arguments passed. If the function receives a different
number of arguments, it terminates the program (with an identifying
message).
Using C with IBM Informix 4GL C-17
Calling a C Function from a 4GL Program
The C function in the next example can operate with one, two, or three
arguments. The purpose of the function is to return the index of the next
occurrence of a given character in a string. The string is the first argument
and is required. The second argument is the character to search for; if it is
omitted, a space character is used. The third argument is an offset at which to
start the search; if it is omitted, zero is used.
#include <fglsys.h>;
#include <fgltypes.h>;
...
...
#define STSIZE 512+1
mint fglindex(mint nargs);
{
int1 theString[STSIZE], theChar[2];
mint offset, pos;
*theChar = ''; /* initialize defaults */
offset = 0;
switch(nargs)
{
case 3: /* fglindex(s,c,n) */
ibm_lib4gl_pushMInt(&offset);
case 2: /* fglindex(s,c) */
ibm_lib4gl_pushQuotedStr(theChar,2);
case 1: /* fglindex(s) */
ibm_lib4gl_pushQuotedStr(theString,STSIZE);
break;
default: /* zero or >;3 parms, ret 0 */
for(;nargs;nargs)
ibm_lib4gl_pushQuotedStr(theString,STSIZE);
ibm_lib4gl_returnMInt(999);
return(1);
}
if (pos = index(theString+offset,*theChar) )
ibm_lib4gl_returnMInt(offset+pos-1);
else
ibm_lib4gl_returnMInt(0);
return(1);
}
The switch statement is useful in popping the correct number of arguments
from the stack. By arranging the valid cases in descending order, the correct
number of arguments can be popped in the correct sequence with minimal
coding. In this example, the C function does not terminate the 4GL program
when given an incorrect number of arguments. Instead, it disposes of all
stacked arguments by popping them as character strings. Then it returns an
impossible value.
C-18 IBM Informix 4GL Reference Manual
Compiling and Executing the Program
Important: A 4GL Rapid Development System program that calls C functions
cannot specify as an argument to the C function a 4GL program variable whose scope
of reference is global.
Compiling and Executing the Program
The version of 4GL you are using determines how you compile and run a 4GL
program that calls C functions. If you are using the 4GL Rapid Development
System, you need to create a customized runner to handle the C functions. If
you are using the C Compiler version, you do not need a customized runner.
For complete information on compiling and executing 4GL programs, see
Chapter 1, “Compiling IBM Informix 4GL Source Files.” For information on
creating a customized runner, see “RDS Programs That Call C Functions” on
page 1-82.
Calling a 4GL Function from a C Program
4GL provides an application programming interface (API) with the
C language that allows you to call 4GL functions from a C program. You can
call either 4GL Rapid Development System functions or C Compiler
functions.
To write a C program that calls 4GL functions
1. Include the fglapi.h header file.
2. Execute the fgl_start( ) macro to perform initialization tasks.
3. Execute the fgl_call( ) macro to call each 4GL function.
4. If the 4GL function displays a form, execute the fgl_exitfm( ) macro
to reset your terminal for character mode.
5. At the end of the program, execute the fgl_end( ) macro to free
resources.
To pass values between the C program and 4GL function, use the push and
pop functions described in “Using the Argument Stack” on page C-5.
Using C with IBM Informix 4GL C-19
Including the fglapi.h File
This section first explains how to use these features of the API with C:
 Including the fglapi.h file
 Initializing values
 Calling 4GL functions
 Handling Interrupt signals
 Compiling and executing the C program
Including the fglapi.h File
You must include the fglapi.h header file in any C program that calls 4GL
functions. This header file defines the fgl_start( ), fgl_call( ), fgl_exitfm( ),
and fgl_end( ) macros and is located in the $INFORMIXDIR/incl directory.
(See Appendix D, “EnvironmentVariables,”for information on how to set the
INFORMIXDIR environment variable.)
You can include fglapi.h, as demonstrated in the following example:
#include <fglapi.h>;
o4Main()
{
...
}
Initializing the Argument Stack
Before you can call a 4GL function in a C program, you must execute the
fgl_start( ) macro. This macro performs the following actions:
 It initializes the argument stack so that you can pass arguments
between the C program and the 4GL functions.
 If you are using the p-code compiler, it specifies the filename (and
path) of the file that contains the 4GL functions.
You can execute this macro once per C program.
C-20 IBM Informix 4GL Reference Manual
Invoking the 4GL Function
The following example demonstrates how to call the fgl_start( ) macro. It
specifies a file named test as the file that contains the 4GL functions:
#include <fglapi.h>;
o4Main()
{
fgl_start("test";
...
}
If you compile the 4GL function to C code, the filename argument is optional
and is ignored if you specify it. In this case, you can call fgl_start( ) as follows:
#include <fglapi.h>;
o4Main()
{
fgl_start();
...
}
The fgl_start( ) macro is described in detail in “fgl_start( )” on page 24.
Invoking the 4GL Function
The C program must perform the following actions to call a 4GL function:
1. Push the argument values that the function expects onto the
argument stack
2. Use the fgl_call( ) macro to identify the name of the 4GL function and
to tell it how many arguments to expect
The 4GL function must perform the following actions to receive arguments
from and to pass values back to the C program:
1. Include the appropriate arguments in the FUNCTION statement
2. Use the DEFINE statement to define variables for all the arguments
passed to the function
3. Use the RETURN statement in the 4GL function to return control to
the C program and to list any values to pass to the calling C program
The C program can then pop the values passed from the function off the
argument stack.
Using C with IBM Informix 4GL C-21
Invoking the 4GL Function
For example, the C program listed on the next page calls a 4GL function
named get_customer( ).
The program passes one argument to the get_customer( ) function. Then
get_customer( ) passes one argument back to the C program. The argument
passed to the function is the filename and path of the demonstration
database. The C program prompts the user for this filename.
The get_customer( ) function displays amenu of the first 10 customers in the
customer table of the specified database. The user then chooses a customer
name from the menu, and the function passes the chosen name back to the
C program. Finally, the C program displays the name of the customer.
#include <fglapi.h>;
#include <fglsys.h>;
#include <fgltypes.h>;
#include <stdio.h>;
o4Main()
{
int1 str[80];
fgl_start("example";
printf("enter the full path name of a STORES database: ";
fflush(stdout);
scanf("%s", str);
ibm_lib4gl_pushQuotedStr(str, strlen(str));
fgl_call(get_customer, 1);
ibm_lib4gl_popQuotedStr(str, 80);
printf("name entered: %s\n", str);
fgl_end();
}
The logic of the 4GL function get_customer( ) is as follows:
FUNCTION get_customer(dbname)
DEFINE dbname CHAR(30),
cust_array ARRAY[50] of CHAR(15),
i INT
DATABASE dbname
DECLARE c1 CURSOR FOR SELECT lname
FROM customer ORDER BY lname
LET i = 1
FOREACH c1 INTO cust_array
LET i = i + 1
END FOREACH
MENU "enter name=>;"
COMMAND cust_array[1] RETURN cust_array[1]
COMMAND cust_array[2] RETURN cust_array[2]
C-22 IBM Informix 4GL Reference Manual
Using Interrupt Signals
COMMAND cust_array[3] RETURN cust_array[3]
COMMAND cust_array[4] RETURN cust_array[4]
COMMAND cust_array[5] RETURN cust_array[5]
COMMAND cust_array[6] RETURN cust_array[6]
COMMAND cust_array[7] RETURN cust_array[7]
COMMAND cust_array[8] RETURN cust_array[8]
COMMAND cust_array[9] RETURN cust_array[9]
COMMAND cust_array[10] RETURN cust_array[10]
END MENU
END FUNCTION
Using Interrupt Signals
An 4GL program can trap Interrupt signals by using the DEFER INTERRUPT
and DEFER QUIT statements. When executing a C program that calls 4GL
functions, you must be careful how you handle interrupts in the C program,
so that you do not confuse the 4GL signal handling with any signal handling
that occurs in the C program.
The fgl_start( ) macro defines functions to call when interrupts occur.When
one of these interrupts occurs, the appropriate function clears the screen and
terminates the program.
By using DEFER INTERRUPT and DEFER QUIT within a 4GL function, you can
control the processing that occurs when the interrupt is detected.
Compiling and Executing the C Program
The method by which you compile and execute a C program that calls a 4GL
function is similar to the method you use to compile and execute a 4GL
program. The following table shows the commands to compile a C program
that calls 4GL functions based on the version of 4GL you are using.
When compiling a C program that calls a 4GL function, you must specify the
-api option of the compilation command. Do not specify the fgiusr.c file on
the command line unless you are calling external C functions from 4GL.
Version of 4GL Compilation Commands
C Compiler c4gl command
RDS fglpc and cfglgo commands
Using C with IBM Informix 4GL C-23
Compiling and Executing the C Program
The following examples illustrate the compilation and execution, using two
source code files and one executable:
 The file mymain.c contains the C program.
 The file my4gl.4gl contains the 4GL function.
 The file myprog.exe is the resulting executable.
Compiling a C Program That Calls C Compiler Functions
To compile a C program that calls a C Compiler function, use the c4gl
command as shown in the following example:
c4gl mymain.c my4gl.4gl -o mymain.exe
./mymain.exe
For complete information on the c4gl command, see “Compiling a 4GL
Module” on page 1-35.
Compiling a C Program That Calls 4GL RDS Functions
To compile a C program that calls a compiled 4GL Rapid Development
System function, use the fglpc and cfglgo commands as shown in the
following example:
fglpc my4gl
cfglgo -api mymain.c -o mymain.exe
./mymain.exe my4gl
For complete information on the fglpc command, see “Compiling an RDS
Source File” on page 1-77. For complete information on the cfglgo command,
see “Creating a Customized Runner” on page 1-85.
C-24 IBM Informix 4GL Reference Manual
Macros for Calling 4GL Functions
Macros for Calling 4GL Functions
Four macros are provided with 4GL for you to use in C programs that call 4GL
functions:
 fgl_start( )
 fgl_call( )
 fgl_exitfm( )
 fgl_end( )
These macros are described in the sections that follow.
fgl_start( )
The fgl_start( ) macro initializes the 4GL argument stack, prepares for signal
handling, and, if you are using the 4GL Rapid Development System, specifies
the path of the file that contains the 4GL functions.
fgl_start(filename)
int1 *filename;
You can specify filename by using either a quoted string or a character
variable. The file extension, .4go or .4gi, is optional.
The following list describes the return codes of fgl_start( ) and the conditions
that evoke them.
You must specify the fgl_start( ) macro before using any of the following
items:
 The fgl_call( ) macro
 The 4GL pushing or popping functions
filename is the filename (and the directory path) of the file that contains the 4GL
functions to call.
0 The macro executed successfully.
< 0 The macro failed.
Using C with IBM Informix 4GL C-25
fgl_call( )
Important: To avoid confusion, you might want to make fgl_start( ) the first
function call in a C program that calls 4GL functions.
If you are using the 4GL Rapid Development System, you must specify
filename. If you are using the C Compiler, filename is optional. For compatibility,
however, you might want to specify an empty string, such as " ", as a
placeholder for filename. Specifying an empty string makes it easier to convert
a C Compiler program to an RDS program.
This code example specifies test as the file that contains the 4GL functions:
#include <fglapi.h>;
o4Main()
{
...
fgl_start("test";
...
}
Once a 4GL function begins execution through use of the fgl_call( ) macro,
the function has access to the arguments passed to it by fgl_call( ) and the
command line arguments passed to the calling C function itself. The
arguments passed by fgl_call( ) are accessed by the 4GL function in the
normal manner—through its argument list. The command-line arguments
passed to the calling C function, however, are accessed by the 4GL function
through use of the 4GL functions ARG_VAL( ) and NUM_ARGS( ). These latter
two functions operate in the normal way, as though the command-line
arguments passed to the C function had been instead used as command-line
arguments to execute the 4GL MAIN function block.
fgl_call( )
The fgl_call( ) macro calls the 4GL function to execute. This macro passes the
following arguments to the 4GL function:
 The name of the function
 The number of arguments being passed
C-26 IBM Informix 4GL Reference Manual
fgl_exitfm( )
The fgl_call( ) macro returns the number of arguments being passed back to
the program from the function.
fgl_call(funcname, nparams)
int1* funcname;
mint nparams;
You must push onto the argument stack any values to be passed to the 4GL
function before executing the fgl_call( ) macro. For more information on
using the push functions, see “The Push Library Functions” on page C-13.
To read any arguments passed back to the C program from the 4GL function,
use the pop functions. For more information on using the pop functions, see
“Receiving Values from 4GL” on page C-7.
The following C source code pushes three arguments onto the argument
stack, and then calls the out_rep1( ) function:
#include <fglapi.h>;
#include <fglsys.h>;
...
o4Main()
{
...
{
fgl_start()
...
ibm_lib4gl_pushQuotedStr(p->;pw_name, strlen(p->;pw_name));
ibm_lib4gl_pushQuotedStr(p->;pw_dir, strlen(p->;pw_dir));
ibm_lib4gl_pushMInt(p->;pw_uid);
fgl_call(out_rep1, 3);
...
}
...
}
fgl_exitfm( )
The fgl_exitfm( ) macro resets the terminal for character mode. Use this
macro after calling a 4GL function that displays a form.
fgl_exitfm( )
funcname is the name of the function to call.
nparams is the number of arguments you are passing to the function.
Using C with IBM Informix 4GL C-27
fgl_end( )
Place this function after any fgl_call( ) macro that causes 4GL to display one
or more forms. This macro resets the terminal for character mode. If you do
not execute this macro, the terminal might behave unusually, and the end
user might be unable to enter any input.
The following example pushes a value onto the argument stack, calls the 4GL
function, pops the returned value, and then executes the fgl_exitfm( ) macro
to reset the terminal to character mode:
#include <fglapi.h>;
#include <fglsys.h>;
#include <stdio.h>;
o4Main()
{
fgl_start()
...
ibm_lib4gl_pushQuotedStr(str, strlen(str));
fgl_call(get_customer, 1);
ibm_lib4gl_popQuotedStr(str, 80);
fgl_exitfm();
...
}
fgl_end( )
The fgl_end( ) macro frees resources resulting from the execution of a
C program that calls a 4GL function.
fgl_end( )
The fgl_end( ) macro performs the following actions:
 Deletes any temp files created by TEXT or BYTE objects
 Closes any files opened by the 4GL function
 Frees the allocated memory
Call this macro at the end of a C program that calls a 4GL function.
C-28 IBM Informix 4GL Reference Manual
Decimal Functions for C
The following example demonstrates popping the value returned from 4GL,
printing this value, and then freeing resources:
#include <fglapi.h>;
#include <fglsys.h>;
#include <stdio.h>;
o4Main()
{
fgl_start()
...
ibm_lib4gl_popQuotedStr(str, 80);
printf("name entered: %s\n", str);
fgl_end()
}
Decimal Functions for C
The data type DECIMAL is a machine-independent method for representing
numbers of up to 32 significant digits, with or without a decimal point, and
with exponents in the range -128 to +126. 4GL provides routines that facilitate
the conversion of DECIMAL-type numbers to and from every data type
allowed in the C language.
DECIMAL-type numbers consist of an exponent and amantissa (or fractional
part) in base 100. In normalized form, the first digit of the mantissa must be
greater than zero.
When used within a C program, DECIMAL-type numbers are stored in a
C structure of the following type:
#define DECSIZE 16
struct decimal
{
int2 dec_exp;
int2 dec_pos;
int2 dec_ndgts;
int1 dec_dgts[DECSIZE];
};
typedef struct decimal dec_t;
The decimal structure and the type definition dec_t can be found in the
header file decimal.h. Include this file in all C source files that use any of the
4GL decimal functions.
Using C with IBM Informix 4GL C-29
Decimal Functions for C
The decimal structure has four parts:
 dec_exp. Holds the exponent of the normalized DECIMAL-type
number. This exponent represents a power of 100.
 dec_pos. Holds the sign of the DECIMAL-type number (1 when the
number is zero or greater; 0 when less than zero).
 dec_ndgts. Contains the number of base-100 significant digits of the
DECIMAL-type number.
 dec_dgts. A character array that holds the significant digits of the
normalized DECIMAL-type number (dec_dgts[0] != 0). Each
character in the array is a one-byte binary number in base 100. The
number of significant digits in dec_dgts is stored in dec_ndgts.
All operations on DECIMAL-type numbers should take place through the
functions provided in the 4GL library, as described in the following pages.
Any other operations, modifications, or analysis of DECIMAL-type numbers
can produce unpredictable results.
The following C function calls are available in 4GL to process DECIMAL-type
numbers.
Function Effect Page
deccvasc( ) Convert C int1 type to DECIMAL type C-30
dectoasc( ) Convert DECIMAL type to C int1 type C-32
deccvint( ) Convert C int type to DECIMAL type C-33
dectoint( ) Convert DECIMAL type to C int type C-34
deccvlong( ) Convert C int4 type to DECIMAL type C-35
dectolong( ) Convert DECIMAL type to C int4 type C-35
deccvflt( ) Convert C float type to DECIMAL type C-36
dectoflt( ) Convert DECIMAL type to C float type C-37
deccvdbl( ) Convert C double type to DECIMAL type C-38
dectodbl( ) Convert DECIMAL type to C double type C-38
decadd( ) Add two DECIMAL numbers C-39
(1 of 2)
deccvasc( )
decsub( ) Subtract two DECIMAL numbers C-39
decmul( ) Multiply two DECIMAL numbers C-39
decdiv( ) Divide two DECIMAL numbers C-39
deccmp( ) Compare two DECIMAL numbers C-40
deccopy( ) Copy a DECIMAL number C-41
dececvt( ) Convert DECIMAL value to ASCII string C-41
decfcvt( ) Convert DECIMAL value to ASCII string C-41
Function Effect Page
(2 of 2)

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
2 [报告]
发表于 2004-10-23 18:38 |只看该作者

[开发现场求助]==C调用4gl函数的问题

汗哪,4GL的函数是什么都不懂.

论坛徽章:
0
3 [报告]
发表于 2004-10-23 20:11 |只看该作者

[开发现场求助]==C调用4gl函数的问题

问题解决了,哈哈哈哈哈!!!!!!!

还真是这个popdec( dTmp );

改成这样popdec( &dTmp );就好了,啊哈哈哈哈!!!!!!

论坛徽章:
0
4 [报告]
发表于 2004-10-23 20:49 |只看该作者

[开发现场求助]==C调用4gl函数的问题

4GL语言还真有人用?
不至于吧
我以为国内根本没人用呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP