Projekat

Općenito

Profil

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