Harbour internals: a_plus_b example¶
a_plus_b_main¶
hernad@nmraka-1:~/devel/git/fmk/harbour/my_samples$ cat a_plus_b_main.prg
function main() local a, b a = 1 b = 1 ? "a=", a, "b=", b ? "a_plus_b =", a_plus_b(a, b) inkey(0) return
hernad@nmraka-1:~/devel/git/fmk/harbour/my_samples$ harbour -n a_plus_b_main.prg
Harbour 1.0.0 Intl. (Rev. 9071) Copyright (c) 1999-2008, http://www.harbour-project.org/ Compiling 'a_plus_b_main.prg'... Lines 12, Functions/Procedures 1 Generating C source output to 'a_plus_b_main.c'... Done.
hernad@nmraka-1:~/devel/git/fmk/harbour/my_samples$ cat a_plus_b_main.c
/* * Harbour 1.0.0 Intl. (Rev. 9071) * GNU C 4.2.3 (32 bit) * Generated C source from "a_plus_b_main.prg" */ #include "hbvmpub.h" #include "hbpcode.h" #include "hbinit.h" HB_FUNC( MAIN ); <<<<<<<<<<<<<<<<< this harbour.prg define main function HB_FUNC_EXTERN( QOUT ); <<<<<<<<<<<<<<<<< references these external functions: HB_FUNC_EXTERN( A_PLUS_B ); <<<<<<<<<<<<<<<<< QOUT, A_PLUS_B, INKEY HB_FUNC_EXTERN( INKEY ); HB_INIT_SYMBOLS_BEGIN( hb_vm_SymbolInit_A_PLUS_B_MAIN ) { "MAIN", {HB_FS_PUBLIC | HB_FS_FIRST | HB_FS_LOCAL}, {HB_FUNCNAME( MAIN )}, NULL }, { "QOUT", {HB_FS_PUBLIC}, {HB_FUNCNAME( QOUT )}, NULL }, { "A_PLUS_B", {HB_FS_PUBLIC}, {HB_FUNCNAME( A_PLUS_B )}, NULL }, { "INKEY", {HB_FS_PUBLIC}, {HB_FUNCNAME( INKEY )}, NULL } HB_INIT_SYMBOLS_EX_END( hb_vm_SymbolInit_A_PLUS_B_MAIN, "a_plus_b_main.prg", 0x0, 0x0002 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_vm_SymbolInit_A_PLUS_B_MAIN #elif defined(HB_MSC_STARTUP) #pragma data_seg( HB_MSC_START_SEGMENT ) static HB_$INITSYM hb_vm_auto_SymbolInit_A_PLUS_B_MAIN = hb_vm_SymbolInit_A_PLUS_B_MAIN; #pragma data_seg() #endif HB_FUNC( MAIN ) { static const BYTE pcode[] = { HB_P_FRAME, 2, 0, /* locals, params */ /* 00003 */ HB_P_LINE, 5, 0, /* 5 */ <<<<<<<<<<<<<< pcode contains line numbers (for debugging, error reports etc) HB_P_ONE, HB_P_POPLOCALNEAR, 1, /* A */ /* 00009 */ HB_P_LINE, 6, 0, /* 6 */ HB_P_ONE, HB_P_POPLOCALNEAR, 2, /* B */ /* 00015 */ HB_P_LINE, 8, 0, /* 8 */ HB_P_PUSHFUNCSYM, 1, 0, /* QOUT */ HB_P_PUSHSTRSHORT, 3, /* 3 */ <<<<<<<<<<<<< push string 'a', '=', 0, HB_P_PUSHLOCALNEAR, 1, /* A */ HB_P_PUSHSTRSHORT, 3, /* 3 */ 'b', '=', 0, HB_P_PUSHLOCALNEAR, 2, /* B */ HB_P_DOSHORT, 4, /* 00037 */ HB_P_LINE, 9, 0, /* 9 */ HB_P_PUSHFUNCSYM, 1, 0, /* QOUT */ <<<<<<<<<<<< push function: QOUT (opcode PUSHFUNCSYM) HB_P_PUSHSTRSHORT, 11, /* 11 */ 'a', '_', 'p', 'l', 'u', 's', '_', 'b', ' ', '=', 0, HB_P_PUSHFUNCSYM, 2, 0, /* A_PLUS_B */ HB_P_PUSHLOCALNEAR, 1, /* A */ HB_P_PUSHLOCALNEAR, 2, /* B */ HB_P_FUNCTIONSHORT, 2, HB_P_DOSHORT, 2, /* 00067 */ HB_P_LINE, 11, 0, /* 11 */ HB_P_PUSHFUNCSYM, 3, 0, /* INKEY */ <<<<<<<<<<<<< inkey pcode = 3 HB_P_ZERO, HB_P_DOSHORT, 1, /* 00076 */ HB_P_LINE, 12, 0, /* 12 */ HB_P_ENDPROC /* 00080 */ }; hb_vmExecute( pcode, symbols ); <<<<<<<<<<<<<< execute pcode }
a_plus_b¶
hernad@nmraka-1:~/devel/git/fmk/harbour/my_samples$ cat a_plus_b.prg
function a_plus_b(a, b) return a + b
hernad@nmraka-1:~/devel/git/fmk/harbour/my_samples$ harbour -n a_plus_b.prg
Harbour 1.0.0 Intl. (Rev. 9071) Copyright (c) 1999-2008, http://www.harbour-project.org/ Compiling 'a_plus_b.prg'... Lines 3, Functions/Procedures 1 Generating C source output to 'a_plus_b.c'... Done.
hernad@nmraka-1:~/devel/git/fmk/harbour/my_samples$ cat a_plus_b.c
/* * Harbour 1.0.0 Intl. (Rev. 9071) * GNU C 4.2.3 (32 bit) * Generated C source from "a_plus_b.prg" */ #include "hbvmpub.h" #include "hbpcode.h" #include "hbinit.h" HB_FUNC( A_PLUS_B ); <<<<<<<<<<<<<<< this prg define harbour function A_PLUS_B <<<<<<<<<<<<<<< it doesn't depends on harbour external functions <<<<<<<<<<<<<<< (there is no HB_FUNC_EXTERN) HB_INIT_SYMBOLS_BEGIN( hb_vm_SymbolInit_A_PLUS_B ) { "A_PLUS_B", {HB_FS_PUBLIC | HB_FS_FIRST | HB_FS_LOCAL}, {HB_FUNCNAME( A_PLUS_B )}, NULL } HB_INIT_SYMBOLS_EX_END( hb_vm_SymbolInit_A_PLUS_B, "a_plus_b.prg", 0x0, 0x0002 ) #if defined(HB_PRAGMA_STARTUP) #pragma startup hb_vm_SymbolInit_A_PLUS_B #elif defined(HB_MSC_STARTUP) #pragma data_seg( HB_MSC_START_SEGMENT ) static HB_$INITSYM hb_vm_auto_SymbolInit_A_PLUS_B = hb_vm_SymbolInit_A_PLUS_B; #pragma data_seg() #endif HB_FUNC( A_PLUS_B ) { static const BYTE pcode[] = { HB_P_FRAME, 0, 2, /* locals, params */ /* 00003 */ HB_P_LINE, 3, 0, /* 3 */ HB_P_PUSHLOCALNEAR, 1, /* A */ <<<<<<<<<< push local parameter 1 HB_P_PUSHLOCALNEAR, 2, /* B */ <<<<<<<<<< push local parameter 2 HB_P_PLUS, <<<<<<<<<< plus operation: P_PLUS opcode HB_P_RETVALUE, <<<<<<<<<< return value from the operation HB_P_ENDPROC /* 00013 */ }; hb_vmExecute( pcode, symbols ); <<<<<<<<<<< execute pcode }
hblnk kreira temp.c source: /tmp/hb-build-hernad-10420.c
#include "hbapi.h" HB_FUNC_EXTERN( HB_GT_CRS ); void _hb_lnk_ForceLink_build( void ) { HB_FUNC_EXEC( HB_GT_CRS ); <<<<<<<<<<<<< GT - execute graphic terminal function (in this case ncurses) } #include "hbinit.h" HB_EXTERN_BEGIN extern char * s_defaultGT; extern char * s_pszLinkedMain; HB_EXTERN_END HB_CALL_ON_STARTUP_BEGIN( hb_lnk_SetDefault_build ) s_defaultGT = "CRS"; HB_CALL_ON_STARTUP_END( hb_lnk_SetDefault_build )
everything is linked with this command:
gcc -oa_plus_b_1 a_plus_b_main.o a_plus_b.o -o ./a_plus_b_1 -I/usr/harbour/include -L/usr/harbour/lib /tmp/hb-build-hernad-10420.c -Wl,--start-group -lharbour -lhbdebug -lhbct -lhbnf -lhbmzip -lhbtip -lxhb -lhbodbc -lhbmysql -lrddado -Wl,--end-group -L/usr/X11R6/lib -lX11 -lncurses -lslang -lm -ldl
object files, archive of object files¶
These include files defines generated C function names Harbour c include files
let's create archive
hernad@nmraka-1:/data/devel/git/fmk/harbour/my_samples$ ar cr liba_plus_b.a a_plus_b.o a_plus_b_main.o
nm liba_plus_b.a
a_plus_b.o: 00000039 T HB_FUN_A_PLUS_B <<<<<<<< c name is: HB_FUN_A_PLUS_B U hb_vmExecute U hb_vmProcessSymbolsEx 00000000 t hb_vm_SymbolInit_A_PLUS_B 00000016 r pcode.2634 00000010 d symbols 00000000 d symbols_table a_plus_b_main.o: U HB_FUN_A_PLUS_B U HB_FUN_INKEY 00000039 T HB_FUN_MAIN <<<<<<<< c name is: HB_FUN_MAIN U HB_FUN_QOUT U hb_vmExecute U hb_vmProcessSymbolsEx 00000000 t hb_vm_SymbolInit_A_PLUS_B_MAIN 00000040 r pcode.2640 00000040 d symbols 00000000 d symbols_table
shared library a_plus_b.so¶
hernad@nmraka-1:/data/devel/git/fmk/harbour/my_samples$ hb-mkslib liba_plus_b.so liba_plus_b.a
hernad@nmraka-1:/data/devel/git/fmk/harbour/my_samples$ ls -l *.so *.a
-rw-r--r-- 1 hernad hernad 3312 2008-08-07 12:20 a_plus_b.a -rwxr-xr-x 1 hernad hernad 6472 2008-08-07 12:24 liba_plus_b.so
my_a_plus_b_c_programme.c¶
This simple c programme is going to use harbour functions from liba_plus_b.so
hernad@nmraka-1:/data/devel/git/fmk/harbour/my_samples$ cat my_a_plus_b_c_programme.c
#include "hbapi.h" HB_FUNC_EXTERN( HB_GT_CRS ); void _hb_lnk_ForceLink_build( void ) { HB_FUNC_EXEC( HB_GT_CRS ); } #include "hbinit.h" HB_EXTERN_BEGIN extern char * s_defaultGT; extern char * s_pszLinkedMain; HB_EXTERN_END HB_CALL_ON_STARTUP_BEGIN( hb_lnk_SetDefault_build ) s_defaultGT = "CRS"; HB_CALL_ON_STARTUP_END( hb_lnk_SetDefault_build )
compile source:
$ gcc my_a_plus_b_c_programme.c -I/usr/harbour/include -L. -L/usr/harbour/lib \ -Wl,--start-group -lharbour -la_plus_b -Wl,--end-group -L/usr/X11R6/lib -lX11 -lncurses -lslang -lm
$ LD_LIBRARY_PATH=.:/usr/harbour/lib $ ./a.out
and voila ... it works :) :