Harbour using C language

549 views
Skip to first unread message

Jacenty

unread,
Dec 15, 2020, 2:28:20 PM12/15/20
to Harbour Users
Hi,

I would like to run some tests therefore I have some questions:

- Where can I find documentation for the Harbour API?
- Will writing a library using C make the application faster?
- Where can I find more examples similar to mine?

Can someone translate my example from Harbour to C

```
PROCEDURE Database( nBase1, nBase2 )

LOCAL cResult

cResult := "Base 1 " + Str( nBase1 ) + "Base 2 " + Str( nBase2 )

RETURN cResult

//----------------------------------------------------------------------------//
#PRAGMA BEGINDUMP

#include "hbapi.h"
HB_FUNC( DATABASE )
{
hb_retc( ? );
}

#PRAGMA ENDDUMP
```

Bien à vous,
Jacenty  

Jacenty

unread,
Dec 19, 2020, 12:56:51 PM12/19/20
to Harbour Users
Hi, 

I have another question:
Can anyone help with the content of this function?
If the parameter is a function?

``` C
UDXAPI void udxDisplayFunc( void (* callback)( void ) );
```

``` Harbour
HB_FUNC( UDXDISPLAYFUNC )
{
udxDisplayFunc( ? );
}
```  


Maurizio la Cecilia

unread,
Dec 22, 2020, 6:41:28 AM12/22/20
to harbou...@googlegroups.com
Hi,
HB_FUNC( UDXDISPLAYFUNC ) is just an Harbour function wrapper to udxDisplayFunc() C function.

HB_FUNC( <HarbourFunctionName> ) declares an Harbour function named <HarbourFunctionName> 

In your sample the Harbour function is directly calling its C counterpart allowing to call udxDisplayFunc() from Harbour code and to execute the same named C function.
I guess the '?' parameter is your added comment...

Best regards.
--
Maurizio
--
--
You received this message because you are subscribed to the Google
Groups "Harbour Users" group.
Unsubscribe: harbour-user...@googlegroups.com
Web: http://groups.google.com/group/harbour-users

---
You received this message because you are subscribed to the Google Groups "Harbour Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/harbour-users/003db8a6-8e70-41ce-b7dc-7746cdb5d615n%40googlegroups.com.


Jacenty

unread,
Dec 22, 2020, 12:11:20 PM12/22/20
to Harbour Users
Hi,

Thank you very much Maurizio for your interest in my question, contrib (x)Harbour did not find a suitable example. 
udxDisplayFunc sets the display callback for the  window. The display callback is called with no parameters. 

In C it looks like this:

```
int main(int argc, char** argv)
{
   udxAppContext  app;
   udxAppInitialize(&app, "Push", NULL, 0, &argc, argv, NULL, NULL);
   udxDisplayFunc( display );

   while (1)
   {
      udxEvent();
   }

}

void  display(void)
{
   printf("Sample data to display\n");
}
```

How will this example be in (x)Harbour, or is it conditioned by internal aspects of the app cancellation?
Where can I find a link with examples?


Best regards.
-- 
Jacent 

Antonio Linares

unread,
Dec 23, 2020, 2:50:23 AM12/23/20
to Harbour Users
Jacent,

This is just an example. function "display" could be converted into a codeblock on a next example:

function Main()

   udxAppInitialize( "Push", hb_argc(), hb_argv() )
   udxDisplayFunc()

   while .T.
      udxEvent()
   end

return nil

#pragma BEGINDUMP

#include <hbapi.h>
#include <stdio.h>

UDXAPI void udxDisplayFunc( void ( * callback )( void ) );

static udxAppContext app;

HB_FUNC( UDXAPPINITIALIZE )
{
   int argc = hb_parni( 2 );
    
   udxAppInitialize( &app, hb_parc( 1 ), NULL, 0, &argc, hb_parc( 3 ), NULL, NULL );      
   hb_ret();
}

static void display( void )
{
   printf( "Sample data to display\n" );

HB_FUNC( UDXDISPLAYFUNC )
{
   udxDisplayFunc( display ); 
}

HB_FUNC( UDXEVENT )
{
   udxEvent();
}

#pragma ENDDUMP

best regards,

Antonio

Jacenty

unread,
Dec 23, 2020, 3:02:00 PM12/23/20
to Harbour Users
Hi Antonio, 

Thank you so much for help, all is well functions udxDisplayFunc i wanted to use in Harbour source code.
obviously your code is fine and it works but only on the C side of the language. 

```
function Main()

   udxAppInitialize( "Push", hb_argc(), hb_argv() )
   udxDisplayFunc( display() )

   while .T.
      udxEvent()
   end

return nil

function display()

   ? "Sample data to display"

return nil
```

Antonio Linares

unread,
Dec 24, 2020, 4:45:39 AM12/24/20
to Harbour Users
function Main()

   udxAppInitialize( "Push", hb_argc(), hb_argv() )
   udxDisplayFunc( { || display() } )

   while .T.
      udxEvent()
   end

return nil

function display()

   ? "Sample data to display"

return nil

Next is to evaluate the codeblock from low level

Antonio Linares

unread,
Dec 24, 2020, 4:56:11 AM12/24/20
to Harbour Users
PHB_ITEM pBlock = NULL;

static void display( void )
{
     if( pBlock && HB_IS_BLOCK( pBlock ) )
        hb_evalBlock0( pBlock );   


HB_FUNC( UDXDISPLAYFUNC )
{
   PHB_ITEM pBlock = hb_param( 1, HB_IT_ANY );

   udxDisplayFunc( display ); 
}

regards

Antonio Linares

unread,
Dec 24, 2020, 4:57:04 AM12/24/20
to Harbour Users
Minor change:

HB_FUNC( UDXDISPLAYFUNC )
{
   pBlock = hb_param( 1, HB_IT_ANY );

   udxDisplayFunc( display ); 
}

Jacenty

unread,
Dec 24, 2020, 6:11:59 AM12/24/20
to Harbour Users
Compilation runs smoothly without errors, the result file without errors, all right
But he has not handed over this function display(), he does not see it yet
he doesn't see her yet.

Jacenty

unread,
Dec 24, 2020, 6:33:31 AM12/24/20
to Harbour Users
static void display( void )
{
     /* if( pBlock && HB_IS_BLOCK( pBlock ) ) */
        hb_evalBlock0( pBlock );   

does not fulfill this condition if
if I make a comment, I get this type of error:

Unrecoverable error 9017: Codeblock expected from hb_vmDoBlock()
Called from (b)EVAL(0)  

Antonio Linares

unread,
Dec 25, 2020, 3:51:54 AM12/25/20
to Harbour Users
Please post here your PRG to test it

thanks

Jacenty

unread,
Dec 25, 2020, 6:28:48 AM12/25/20
to Harbour Users
I searched all files in contrib, there is no example anywhere that points to my example and function hb_evalBlock0 there is no such.

This is exactly what it looks like:

``` C executable file
int main( int* argc, char** argv )
{
   udxInitialize( &argc, argv )

   udxDisplayFunc( display );

   /* udxLoop() calls the application's appropriate callbacks, polls the data entry devices car inspections. */
   udxLoop( )

   return 0;
}

static void display( void )
{
   printf( "Sample data to display\n" );
}
```
This is the minimum to check registration in C


``` (x)Harbour executable file
function Main()

   udxInitialize( 0, NIL )

   udxDisplayFunc( {|| display() } )

   udxLoop()

return nil

function display()

   ? "Sample data to display"

return nil
```

``` (x)Harbour c file

HB_FUNC( UDXINITIALIZE )
{
  /* 
   int argc = hb_parni( 1 );
   udxInitialize( &argc, hb_parc( 2 ) );
   hb_ret(); 
   the above makes a mistake so I shortened it to this option  */
   udxInitialize( 0, NULL )
}

PHB_ITEM pBlock = NULL;
static void display( void )
{
   /* This condition is not executed and it skips the hb_evalBlock0 */function
   if( pBlock && HB_IS_BLOCK( pBlock ) )
   hb_evalBlock0( pBlock );
}

/* UDXAPI void udxDisplayFunc( void ( * callback )( void ) ); */
HB_FUNC( UDXDISPLAYFUNC )
{
   pBlock = hb_param( 1, HB_IT_SYMBOL );
   udxDisplayFunc( display );
}

/* UDXAPI void udxLoop( void ) */
HB_FUNC( UDXLOOP )
{
   udxLoop();
}

``` The End

It's really strange that no one did this in Contrib ?

Thank you for your help.

Antonio Linares

unread,
Dec 26, 2020, 3:28:10 AM12/26/20
to Harbour Users
It will not work using  HB_IT_SYMBOL. 

Use HB_IT_BLOCK or HB_IT_ANY 

Jacenty

unread,
Dec 26, 2020, 4:05:32 AM12/26/20
to Harbour Users
Did not help. 

```
PHB_ITEM pBlock = NULL;
static void display( void )
{
   if( pBlock && HB_IS_BLOCK( pBlock ) ) /* does not fulfill this condition */
   {
      hb_evalBlock0( pBlock );
   }
   else
   {
      hb_errRT_BASE_SubstR( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
   }
}
```
or 

```
PHB_ITEM pBlock = NULL;
static void display( void )
{
      hb_evalBlock0( pBlock );
}
```
it generates an error:  
Unrecoverable error 9017: Codeblock expected from hb_vmDoBlock() 

Jacenty

unread,
Dec 26, 2020, 4:35:27 AM12/26/20
to Harbour Users
In the first example of the display() function:

Error BASE/3012  Argument error: UDXLOOP
The first argument is not a string with function/procedure name that should be called.

Antonio Linares

unread,
Dec 27, 2020, 5:08:18 AM12/27/20
to Harbour Users
Please try this change:

#include <hbapiitm.h>

static void display( void )
{
      hb_evalBlock0( pBlock );
      hb_itemRelease( pBlock ); 
}

HB_FUNC( UDXDISPLAYFUNC )
{
   pBlock = hb_itemParam( 1, HB_IT_BLOCK );
   udxDisplayFunc( display );

Antonio Linares

unread,
Dec 27, 2020, 5:18:33 AM12/27/20
to Harbour Users
pBlock = hb_itemParam( 1 ); 

Jacenty

unread,
Dec 27, 2020, 2:07:10 PM12/27/20
to Harbour Users
Thanks a lot, the application is running and works the same as in C, but with small changes:

   udxDisplayFunc( @display() )

Will this difference make a big difference?
Passing a variable by reference means that a reference to the value of the argument is passed instead of a copy of the value.  

Sending through a block of code seems like a better way { || display() }









Jacenty

unread,
Dec 27, 2020, 2:13:50 PM12/27/20
to Harbour Users
Sorry i forgot to write, 

there is this bug when using this function:
udxDisplayFunc( { || display() } )  
Error BASE/1004  No exported method: EVAL

Antonio Linares

unread,
Dec 28, 2020, 2:46:13 AM12/28/20
to Harbour Users
It is also fine the way you are doing it using a symbol:

udxDisplayFunc( @display() )  // thats the "symbol" of function display()

Reply all
Reply to author
Forward
0 new messages