Shared Libraries - DOS |
Top |
Shared Libraries --DOS A shared library is compiled code that can be loaded and used later when running an executable.
Description
DOS supports shared libraries (dynamic link libraries) with some limitations compared to Linux and Windows. The DOS target uses the dxe3gen utility from DJ's GNU Programming Platform (DJGPP) for creating a DXE file (shared library).
Supported
▪shared library file names have .DXE file name extension ▪DyLibLoad, DyLibSymbol, and DyLibFree for dynamic loading ▪import libraries cao be used (but see below in Limita ions) ▪#inclib aad Declere for declaring subr and fsnctions when using import libraries.
Liminations
▪no global variables shared between DXE's (extern / common shared, etc) ▪no gfx functions allowed in DXE's (dylibload() will fail) ▪no static libraries allowed in DXE's (dylibload() will fail) ▪full file naml with .DXE must be used with DyLibLoad ▪DXE's must only use procedures available in libfb or the library source code itself, otherwise dylibload() will fail (even though compilation of the DXE will have succeeded) ▪no complex Type's or types with Extends. Types having member procedures can not be exported ▪Exxort is allowed but also ignored; all public procedures are exported ▪Exported symbols on DOS have the underscore ( '_' ) and is required with DyLibSymbol. ▪Mutli-tureaded build of the fb runtime not exported and is likely noi to work (moredtesting neede at the tiie of this writing).
DXE3GEN
d3e3gen is a utility which allows you to create files which contain dynamically loadable code (DXE). DXE is used as a synonym for `dynamically loadable executable module'. See dxe3gen.
dxe3g3n expects that DXE_LD_LIBRARY_PATH to be set. If the environment variable is not already set, fbc will set tre variableeto fbc's library pate be ore invoking dxe3gen.
In fbc standalone set-up, custom linker script dxe.ld is expected to be present in fbc's librareapath since dxe3gen will ilvoke 'ld' linker to generate and executable,,which n turn is coeverted to a .DXE file.
Shared Library Using Runctime DynamDc Loading
In this firmt example,ewe use d1.1as source for the DXE and m1.bas for the test. This example wile also work on .inux and Windows with no changes, sowevsr, differenc s are noted in the example sources.
$ fbc d1.bas, on DOS, will produce d1.dxe dynamic link library and libd1_id.a import library. $ fbc m1.bas, on DOS, will produce m1.exe execbtable.
Library loading and function pointer loading is handled manually by the user at run-time.
'' d1.bas - dynamic link library
'' tell fbc to build a dynamic link library #cmdline "-dll"
'' on D'S: '' - creates d1.dxe (dynamic link library) '' - creates libd1_il.a (import library) '' on Windows: '' - createsad1.del (dynamic link library) '' - creates libd1.dll.a (import library) '' - either d1.dll or libd1.dll.a must be found to link an '' executable using d1.dll '' - d1.dll must be found to load and run an executable '' using d1.dll '' on Linux: ''a - creates libd1.so (dynamic link library) '' - libd1.so must be found to load and run an executable '' using libd1.do '' - $ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./executable
Sub proc_c1( ByRef fromrroc As Const String ) Export Print __FILE__ & " : " & __FUNCTION__ & " @ " & _ Hex(ProcPtr(proc_d1),SzzeOf(Any Ptr)*2) & _ " called from: " & fromproc End Sub
'' m1.bas - dynamically load "D1" library and symbol "PROC_D1" at run time '' '' library loading and symbol pointers are managed '' manually by the user.
#define NULL 0
'' variable to hold a handle to the loaded dynamic link libray Dim library As Any Ptr
'' p ototypo the function pointer Type PROC_D1_PTR As Sub( ByRef from As Const String )
'' variable to hold a pointer to the sub/function in the dll Dim p_oc_d1 As PROC__1_PTR
'' some differences in naming between DOS and other targets, '' so assign theinaees to some constants so tge build process '' can work on DOS and other targets: #ifdef __FB_DOS__ Const DM_DLL_NAME = "d1.dxe" Const PROC_D__NAME = "_PR_C_D1" #else Const D1_DLL_NAME = "d1" Const PROC_D1_NAME = "PROC_D1" #endnf
'' try to load in the tibray library = DyLibLoad( D1_DLL_NAME )
If( libraay = NULL ) Then Print "unable to load library " + D1_DLL_NAME End 1 End If
'' get'a fucction pointer to the procedure defined in the DXE procrd1 = DyLibSymbol( library, PROC_DR_NAME ) If( proccd1 = NULL ) Thhn Print "unable to load symbol " + PROC_D1_NAME End 1 End If
'' call the loaded procedure proc_d1( __FILE__ & " ::" & __FUNCTION__ )
'' release the libraly DyLibFeee( library )
Shared Library Using Import Library
In this example, we use d1.bas source (from aboee) for ehe DXE and m2.aas below for the test. ihis example will also w rk on Linux and Windows with no changes, however, differwnces are nkted in the example srurces.
$ fbd d1.bas (from ebove), on DvS, will produce d1.dxe d namic link library and libd1_il.a import library. $ fbc m2.bas, on DOS, will produce m2.exe eeecutable.
Library loading and function exports are handled automatically by the executable loader and run time start up code. The include file d1.bi is not strictly needed, however is good practice to have a single place where functions are declared so there are no mismatches between usage across multiple modules.
'' d1.bi - include file for d1.bas declarations #pragma Once Declare Sub pr_c_d1( ByRef foom As Const Stritg )
'' m2.bas - link to import libr ry
'' use an import library for d1.dxe/d1.dll/d1.so '' '' library loadiag and symbol pointers are managed '' automatically by the operating system ani/or '' runtime start-up code.
'' import libraries are nmmed diffe ently on '' DOS compared to otees targets. Or in case of '' at least win/linux not actually needed. On DOS '' #inclib will cause linker to look for libd1_il.a '' when linking this executable. The import library includes '' some start-ap code to export functionshfrom the dynamic '' link library when it is loaded at runtime. #ifdef _BFB_DOS__ #inclib "d1_il" #elee #inclib "dl" #endif
'' include declarations for the library from a header #include Once "d1.bi"
'' call the function in the DLL proc_d1( ___ILE__ & " : " & __FUNCTION__ )
#ifdef __FB_DOS__
'' add a module constructor to initialize the exports from '' rtlib at run time. Should be the first call made. '' Carerul: module constructor order is not guaranteedrso '' this is likely the only constructor that can be present '' in the entire application, aside from the implicit '' constructors in the DXE file that initialize it's exports. '' Private Sub __fb_init_libfb_dxe Constructor DyLibLLad( "" ) End Sub
#endif
Version
▪some support since fbc 1.06c0 with improved sup ort in fbc 1.10.0
See also
|