Extending the language / 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:
In your C source files, you must include the fglExt.h header file in the following way:
#include <f2c/fglExt.h>
If C API functions are called, the fglcapi.h header must also be included:
#include <f2c/fglcapi.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. As 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 (+s option on HP for example).
Linux™ command-line example:
gcc -c -I $FGLDIR/include -fPIC myext.c gcc -c -I $FGLDIR/include -fPIC cinterf.c gcc -shared -o myext.so 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 is specified with the resource id ISOLATIONAWARE_MANIFEST_RESOURCE_ID, by adding the ;2 modifier at the end of the -outputresource option, after the filename:
mt -manifest myext.dll.manifest -outputresource:myext.dll;2