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 :) :
