Creating C-Extensions

Custom C-Extensions must be provided to the runtime system as Shared Objects (.so) on UNIX™, and as Dynamically Loadable Libraries (.DLL) on Windows®.

In order to create a C-Extension, you must:

  1. Define the list of user functions in the C interface file, by including the fglExt.h header file.
  2. Compile the C interface file with your C compiler.
  3. Modify your C source modules by including the fglExt.h header file.
  4. Compile the C interface file and the C modules with the position-independent code option.
  5. Create the shared library with the compiled C interface file and C modules by linking with the libfgl runtime system library.

Include the fglExt.h header file in the following way:

#include "f2c/fglExt.h"

When migrating from IBM® Informix® 4GL, it is possible that existing C-Extension sources include Informix specific headers like sqlhdr.h or decimal.h. You can either remove or keep the original includes, but if you want to keep them, the Informix specific header files must be included before the fglExt.h header file, in order to let fglExt.h detect that typedefs such as dec_t or dtime_t are already defined by Informix headers. If you include Informix headers after fglExt.h, you will get a compilation error.

Since fglExt.h defines all Informix-like typedef structures, you can remove the inclusion of Informix specific header files.

The C functions that are implemented in the C-Extension libraries must be known by the runtime system. To do so, each C-Extension library must publish its functions in a UsrFunction array, which is read by the runtime system when the module is loaded. The UsrFunction array describes the user functions by specifying the name of the function, the C function pointer, the number of parameters and the number of returned values. You typically define the UsrFunction array in the C interface file.

After compiling the C sources, you must link them together with the libfgl runtime system library.

Carefully read the man page of the ld dynamic loader, and any documentation of your operating system related to shared libraries. Some platforms require specific configuration and command line options when linking a shared library, or when linking a program using a shared library.

Linux® command-line example:

gcc -c -I $FGLDIR/include -fPIC myext.c 
gcc -c -I $FGLDIR/include -fPIC cinterf.c 
gcc -shared -o myext.o cinterf.o -L$FGLDIR/lib -lfgl

Windows command-line example using Visual C 8.0 and higher (with SxS manifest for the DLL!):

cl /DBUILDDLL /I%FGLDIR%/include /c myext.c 
cl /DBUILDDLL /I%FGLDIR%/include /c cintref.c 
link /dll /manifest /out:myext.dll myext.obj cinterf.obj %FGLDIR%\lib\libfgl.lib 
mt -manifest myext.dll.manifest -outputresource:myext.dll

If you build your DLL with a version of Microsoft™ Visual C++ that is different from the version used to build FGLRUN.EXE, the DLL must get private dependencies other than the process default. For example, when the C-Extension DLL needs the Visual C 9.0 runtime library MSVCR90.DLL, while the FGLRUN.EXE was build with VC 10 and needs MSVCR100.DLL. Private dependencies are specified with the resource id ISOLATIONAWARE_MANIFEST_RESOURCE_ID, by adding the ;2 modifier at the end of the -outputresource option, after the file name:

mt -manifest myext.dll.manifest -outputresource:myext.dll;2
To simplify compilation and linking of a C-Extension library, it is also possible to use the fglmkext command line tool:
fglmkext -o module_a.c module_b.c

The fglmkext command line tool contains platform-specific C compiler and linker options required to build a C Extension library.