read/write harbour class in C

391 views
Skip to first unread message

Antonino Perricone

unread,
Jun 16, 2015, 4:02:58 AM6/16/15
to harbou...@googlegroups.com
Hello,
I am trying to read and to write harbour class from C code.
For example, I have this class:
class LVColumn
   DATA nFormat AS NUMERIC INIT 0
   DATA nWidth AS NUMERIC INIT 100
   DATA cText AS CHARACTER INIT "Column"
   DATA nIndex 
   DATA nOrder 
   DATA nWidthMin 
   
   METHOD Test()
endclass
To read the class from C code I do:
#include <hbapi.h>
#include <hbapicls.h>
#include <hbapiitm.h>
#include <stdio.h>

#define CLASSNAME "LVCOLUMN"
struct LVCOLUMNDATA
{
   HB_USHORT classId;
   
   HB_SIZE nFormat;
   HB_SIZE nWidth;
   HB_SIZE cText;
   HB_SIZE nIndex;
   HB_SIZE nOrder;
   HB_SIZE nWidthMin;
   PHB_SYMB Test;
} lvColumnData = {0};

void Init_LVCOLUMN()
{
   if(lvColumnData.classId == 0)
   {
      lvColumnData.classId   = hb_clsFindClass(CLASSNAME, NULL);
      lvColumnData.cText     = hb_clsGetVarIndex(lvColumnData.classId,hb_dynsymGet("cText"));
      lvColumnData.nFormat   = hb_clsGetVarIndex(lvColumnData.classId,hb_dynsymGet("nFormat"));
      lvColumnData.nWidth    = hb_clsGetVarIndex(lvColumnData.classId,hb_dynsymGet("nWidth"));  
      lvColumnData.nIndex    = hb_clsGetVarIndex(lvColumnData.classId,hb_dynsymGet("nIndex"));
      lvColumnData.nOrder    = hb_clsGetVarIndex(lvColumnData.classId,hb_dynsymGet("nOrder"));
      lvColumnData.nWidthMin = hb_clsGetVarIndex(lvColumnData.classId,hb_dynsymGet("nWidthMin"));
   }
}

HB_FUNC( PRINTCOL  ) 
{
   PHB_ITEM pItem = hb_param( 1, HB_IT_OBJECT );
   PHB_ITEM data;
   Init_LVCOLUMN();
   
   if(pItem==0 || !hb_extIsObject(1) || hb_objGetClass(pItem)!=lvColumnData.classId)
      return; //invalid input
      
   data = hb_itemArrayGet(pItem,lvColumnData.cText); 
   printf("Column \"%s\"",hb_itemGetC(data));
   data = hb_itemArrayGet(pItem,lvColumnData.nFormat);
   if(!HB_IS_NIL(data)) printf(" format:%i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,lvColumnData.nIndex);
   if(!HB_IS_NIL(data)) printf(" index:%i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,lvColumnData.nOrder);
   if(!HB_IS_NIL(data)) printf(" order:%i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,lvColumnData.nWidth);
   if(!HB_IS_NIL(data)) printf(" width %i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,lvColumnData.nWidthMin);
   if(!HB_IS_NIL(data)) printf(" min %i",hb_itemGetNI(data));
   printf(" Test %i", lvColumnData.Test);
   printf("\r\n");   
}
My questions are:
  1. There is a better way to reflect an harbour class with a C struct?
  2. How can I found and call Test method?
  3. How can I create a new LVCOLUMN class from C code?
Sincerely, I hope there is a better way to manage Harbour class from C... May from C++ code?

Regards,
Antonino



Bernard Mouille [w]

unread,
Jun 16, 2015, 7:47:59 AM6/16/15
to harbou...@googlegroups.com

Hello Antonio,

 

I joined a basic sample prg.

 

Look in Harbour sources : #pragma BEGINDUMP for other samples.

 

Regards,

 

Bernard

 


De : harbou...@googlegroups.com [mailto:harbou...@googlegroups.com] De la part de Antonino Perricone
Envoyé : mardi 16 juin 2015 10:03
À : harbou...@googlegroups.com
Objet : [harbour-users] read/write harbour class in C

--
--
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.
For more options, visit
https://groups.google.com/d/optout.

GetConsoleInfos.txt

Antonino Perricone

unread,
Jun 16, 2015, 9:04:39 AM6/16/15
to harbou...@googlegroups.com
Bernard thank you for interest, 
In harbour sources there is no BEGINDUMP, all c code is inside c files.
Your example returns a rectangle as array, what I want to do is return a rectangle as class with "data" left, right, top and bottom.
I hope I have explained better this time.
Regards,
Perry

To unsubscribe from this group and stop receiving emails from it, send an email to harbour-users+unsubscribe@googlegroups.com.
For more options, visit
https://groups.google.com/d/optout.

Bernard Mouille [w]

unread,
Jun 16, 2015, 10:02:43 AM6/16/15
to harbou...@googlegroups.com

Antonio,

I am not in my house.

If nobody give you an answer, I look this in 4 days.

Regards,

Bernard

 

Look in the include folder of harbour hbapi.h the type input and output :

 

extern HB_EXPORT HB_ULONG     hb_parinfo( int iParam ); /* Determine the param count or data type */

extern HB_EXPORT HB_SIZE      hb_parinfa( int iParamNum, HB_SIZE nArrayIndex ); /* retrieve length or element type of an array parameter */

extern HB_EXPORT PHB_ITEM     hb_param( int iParam, long lMask ); /* retrieve a generic parameter */

extern HB_EXPORT PHB_ITEM     hb_paramError( int iParam ); /* Returns either the generic parameter or a NIL item if param not provided */

extern HB_EXPORT HB_BOOL      hb_extIsArray( int iParam );

extern HB_EXPORT HB_BOOL      hb_extIsObject( int iParam );

 

extern HB_EXPORT const char * hb_parc( int iParam ); /* retrieve a string parameter */

extern HB_EXPORT const char * hb_parcx( int iParam ); /* retrieve a string parameter */

extern HB_EXPORT HB_SIZE      hb_parclen( int iParam ); /* retrieve a string parameter length */

extern HB_EXPORT HB_SIZE      hb_parcsiz( int iParam ); /* retrieve a by-reference string parameter length, including terminator */

extern HB_EXPORT const char * hb_pards( int iParam ); /* retrieve a date as a string YYYYMMDD */

extern HB_EXPORT char *       hb_pardsbuff( char * szDate, int iParam ); /* retrieve a date as a string YYYYMMDD */

extern HB_EXPORT long         hb_pardl( int iParam ); /* retrieve a date as a long integer */

extern HB_EXPORT double       hb_partd( int iParam ); /* retrieve a timestamp as a double number */

extern HB_EXPORT HB_BOOL      hb_partdt( long * plJulian, long * plMilliSec , int iParam ); /* retrieve a timestamp as two long numbers */

extern HB_EXPORT int          hb_parl( int iParam ); /* retrieve a logical parameter as an int */

extern HB_EXPORT int          hb_parldef( int iParam, int iDefValue ); /* retrieve a logical parameter as an int, return default value if parameter isn't logical */

extern HB_EXPORT double       hb_parnd( int iParam ); /* retrieve a numeric parameter as a double */

extern HB_EXPORT int          hb_parni( int iParam ); /* retrieve a numeric parameter as a integer */

extern HB_EXPORT int          hb_parnidef( int iParam, int iDefValue ); /* retrieve a numeric parameter as a integer, return default value if parameter isn't numeric */

extern HB_EXPORT long         hb_parnl( int iParam ); /* retrieve a numeric parameter as a long */

extern HB_EXPORT long         hb_parnldef( int iParam, long lDefValue ); /* retrieve a numeric parameter as a long, return default value if parameter isn't numeric */

extern HB_EXPORT HB_ISIZ      hb_parns( int iParam ); /* retrieve a numeric parameter as a HB_SIZE */

extern HB_EXPORT HB_ISIZ      hb_parnsdef( int iParam, HB_ISIZ nDefValue ); /* retrieve a numeric parameter as a HB_SIZE, return default value if parameter isn't numeric */

extern HB_EXPORT HB_MAXINT    hb_parnint( int iParam ); /* retrieve a numeric parameter as a HB_MAXINT */

extern HB_EXPORT HB_MAXINT    hb_parnintdef( int iParam, HB_MAXINT nDefValue ); /* retrieve a numeric parameter as a HB_MAXINT, return default value if parameter isn't numeric */

extern HB_EXPORT void *       hb_parptr( int iParam ); /* retrieve a parameter as a pointer */

extern HB_EXPORT void *       hb_parptrGC( const HB_GC_FUNCS * pFuncs, int iParam ); /* retrieve a parameter as a pointer if it's a pointer to GC allocated block */

#ifndef HB_LONG_LONG_OFF

extern HB_EXPORT HB_LONGLONG  hb_parnll( int iParam ); /* retrieve a numeric parameter as a long long */

#endif

 

extern HB_EXPORT const char * hb_parvc( int iParam, ... ); /* retrieve a string parameter */

extern HB_EXPORT const char * hb_parvcx( int iParam, ... ); /* retrieve a string parameter */

extern HB_EXPORT HB_SIZE      hb_parvclen( int iParam, ... ); /* retrieve a string parameter length */

extern HB_EXPORT HB_SIZE      hb_parvcsiz( int iParam, ... ); /* retrieve a by-reference string parameter length, including terminator */

extern HB_EXPORT const char * hb_parvds( int iParam, ... ); /* retrieve a date as a string YYYYMMDD */

extern HB_EXPORT char *       hb_parvdsbuff( char * szDate, int iParam, ... ); /* retrieve a date as a string YYYYMMDD */

extern HB_EXPORT long         hb_parvdl( int iParam, ... ); /* retrieve a date as a long integer */

extern HB_EXPORT double       hb_parvtd( int iParam, ... ); /* retrieve a timestamp as a double number */

extern HB_EXPORT HB_BOOL      hb_parvtdt( long * plJulian, long * plMilliSec , int iParam, ... ); /* retrieve a timestamp as two long numbers */

extern HB_EXPORT int          hb_parvl( int iParam, ... ); /* retrieve a logical parameter as an int */

extern HB_EXPORT double       hb_parvnd( int iParam, ... ); /* retrieve a numeric parameter as a double */

extern HB_EXPORT int          hb_parvni( int iParam, ... ); /* retrieve a numeric parameter as a integer */

extern HB_EXPORT long         hb_parvnl( int iParam, ... ); /* retrieve a numeric parameter as a long */

extern HB_EXPORT HB_ISIZ      hb_parvns( int iParam, ... ); /* retrieve a numeric parameter as a HB_SIZE */

extern HB_EXPORT HB_MAXINT    hb_parvnint( int iParam, ... ); /* retrieve a numeric parameter as a HB_MAXINT */

extern HB_EXPORT void *       hb_parvptr( int iParam, ... ); /* retrieve a parameter as a pointer */

extern HB_EXPORT void *       hb_parvptrGC( const HB_GC_FUNCS * pFuncs, int iParam, ... ); /* retrieve a parameter as a pointer if it's a pointer to GC allocated block */

#ifndef HB_LONG_LONG_OFF

extern HB_EXPORT HB_LONGLONG  hb_parvnll( int iParam, ... ); /* retrieve a numeric parameter as a long long */

#endif

 

extern HB_EXPORT int    hb_pcount( void );          /* returns the number of suplied parameters */

extern HB_EXPORT void   hb_ret( void );             /* post a NIL return value */

extern HB_EXPORT void   hb_retc( const char * szText );  /* returns a string */

extern HB_EXPORT void   hb_retc_null( void );       /* returns an empty string */

extern HB_EXPORT void   hb_retc_buffer( char * szText ); /* sames as above, but accepts an allocated buffer */

extern HB_EXPORT void   hb_retc_const( const char * szText ); /* returns a string as a pcode based string */

extern HB_EXPORT void   hb_retclen( const char * szText, HB_SIZE nLen ); /* returns a string with a specific length */

extern HB_EXPORT void   hb_retclen_buffer( char * szText, HB_SIZE nLen ); /* sames as above, but accepts an allocated buffer */

extern HB_EXPORT void   hb_retclen_const( const char * szText, HB_SIZE nLen ); /* returns a string with a specific length formed from a constant buffer */

extern HB_EXPORT void   hb_retds( const char * szDate );  /* returns a date, must use YYYYMMDD format */

extern HB_EXPORT void   hb_retd( int iYear, int iMonth, int iDay ); /* returns a date */

extern HB_EXPORT void   hb_retdl( long lJulian );   /* returns a long value as a julian date */

extern HB_EXPORT void   hb_rettd( double dTimeStamp );   /* returns a double value as a timestamp */

extern HB_EXPORT void   hb_rettdt( long lJulian, long lMilliSec );   /* returns two long values as a timestamp */

extern HB_EXPORT void   hb_retl( int iTrueFalse );  /* returns a logical integer */

extern HB_EXPORT void   hb_retnd( double dNumber ); /* returns a double */

extern HB_EXPORT void   hb_retni( int iNumber );    /* returns a integer number */

extern HB_EXPORT void   hb_retnl( long lNumber );/* returns a long number */

extern HB_EXPORT void   hb_retns( HB_ISIZ nNumber );/* returns a size */

extern HB_EXPORT void   hb_retnint( HB_MAXINT nNumber );/* returns a long number */

extern HB_EXPORT void   hb_retnlen( double dNumber, int iWidth, int iDec ); /* returns a double, with specific width and decimals */

extern HB_EXPORT void   hb_retndlen( double dNumber, int iWidth, int iDec ); /* returns a double, with specific width and decimals */

extern HB_EXPORT void   hb_retnilen( int iNumber, int iWidth ); /* returns a integer number, with specific width */

extern HB_EXPORT void   hb_retnllen( long lNumber, int iWidth ); /* returns a long number, with specific width */

extern HB_EXPORT void   hb_retnintlen( HB_MAXINT nNumber, int iWidth ); /* returns a long long number, with specific width */

extern HB_EXPORT void   hb_reta( HB_SIZE nLen );  /* returns an array with a specific length */

extern HB_EXPORT void   hb_retptr( void * ptr );  /* returns a pointer */

extern HB_EXPORT void   hb_retptrGC( void * ptr );  /* returns a pointer to an allocated memory, collected by GC */

#ifndef HB_LONG_LONG_OFF

extern HB_EXPORT void   hb_retnll( HB_LONGLONG lNumber );/* returns a long long number */

extern HB_EXPORT void   hb_retnlllen( HB_LONGLONG lNumber, int iWidth ); /* returns a long long number, with specific width */

#endif

 


De : harbou...@googlegroups.com [mailto:harbou...@googlegroups.com] De la part de Antonino Perricone
Envoyé : mardi 16 juin 2015 15:05
À : harbou...@googlegroups.com
Objet : Re: [harbour-users] read/write harbour class in C

To unsubscribe from this group and stop receiving emails from it, send an email to harbour-user...@googlegroups.com.

Antonino Perricone

unread,
Jun 16, 2015, 10:37:00 AM6/16/15
to harbou...@googlegroups.com
Bernard, I saw hbapi.h and hbapicls.h and hbapiitm.h 
I looked the code also, for example It looks like to create a class from c code I need to call hb_clsAssociate. is it correct?
About the question n.2, I must use hb_itemDo but how can I get the method, there is hb_clsMethodName that from class and method index get the method name, we need a function that return the method item with the same parameters, and another that from method name return the method index.
But maybe all this things are incorrect, if there is a better way to manipolate the harbour classes from C code.
Regards,
Perry


Antonino Perricone

unread,
Jun 19, 2015, 9:38:10 AM6/19/15
to harbou...@googlegroups.com
After some tests I made this:
#include <hbclass.ch>

class ClassTest
   DATA nFormat AS NUMERIC INIT 0
   DATA nWidth AS NUMERIC INIT 100
   DATA cText AS CHARACTER INIT "Colonna"
   DATA nIndex 
   DATA nOrder 
   DATA nWidthMin 
   
   METHOD Test() //Directly C Code
   METHOD AddText()
endclass

METHOD AddText() CLASS ClassTest
   ::cText += " - Added from Harbour code"
return nil

procedure main()
   local col0 := ClassTest():New()
   local col1 := ClassTest():New()
   col1:cText := "Perry"
   col1:nWidthMin := 50
   
   col0:Test()
   CallMember(col1)
   col1:Test()
   col0 := GetNewCol()
   col0:Test()   
return

#pragma BEGINDUMP
#include <hbapi.h>
#include <hbapicls.h>
#include <hbapiitm.h>
#include <stdio.h>
#include <hbstack.h>

#define CLASSNAME "CLASSTEST"
struct CLASSTESTDATA
{
   HB_USHORT classId;
   
   HB_SIZE nFormat;
   HB_SIZE nWidth;
   HB_SIZE cText;
   HB_SIZE nIndex;
   HB_SIZE nOrder;
   HB_SIZE nWidthMin;
   PHB_SYMB Test;
} ClassTestData = {0};

void Init_ClassTest()
{
   if(ClassTestData.classId == 0)
   {
      ClassTestData.classId   = hb_clsFindClass(CLASSNAME, NULL);
      ClassTestData.cText     = hb_clsGetVarIndex(ClassTestData.classId,hb_dynsymGet("cText"));
      ClassTestData.nFormat   = hb_clsGetVarIndex(ClassTestData.classId,hb_dynsymGet("nFormat"));
      ClassTestData.nWidth    = hb_clsGetVarIndex(ClassTestData.classId,hb_dynsymGet("nWidth"));  
      ClassTestData.nIndex    = hb_clsGetVarIndex(ClassTestData.classId,hb_dynsymGet("nIndex"));
      ClassTestData.nOrder    = hb_clsGetVarIndex(ClassTestData.classId,hb_dynsymGet("nOrder"));
      ClassTestData.nWidthMin = hb_clsGetVarIndex(ClassTestData.classId,hb_dynsymGet("nWidthMin"));
   }
}

HB_FUNC( CALLMEMBER )
{
   PHB_ITEM pItem = hb_param(1, HB_IT_OBJECT );
   hb_objSendMsg(pItem,"AddText",0);   
   hb_ret();
}

HB_FUNC( GETNEWCOL  ) 
{
   PHB_ITEM pItem = hb_itemNew(NULL);
   Init_ClassTest();
   hb_clsAssociate( ClassTestData.classId );
   pItem = hb_stackReturnItem();
   hb_itemArrayPut(pItem,ClassTestData.cText, hb_itemPutC(NULL,"From C code"));
   hb_itemArrayPut(pItem,ClassTestData.nWidthMin, hb_itemPutNI(NULL, 611));
}

HB_FUNC( CLASSTEST_TEST  ) 
{
   PHB_ITEM pItem = hb_stackSelfItem();
   PHB_ITEM data;
   Init_ClassTest();
   
   if(pItem==0 || hb_objGetClass(pItem)!=ClassTestData.classId)
   {
            if(pItem==0) printf("no self\r\n");
      else  if(hb_objGetClass(pItem)!=ClassTestData.classId) printf("self is not a \"" CLASSNAME "\" (it is %i)\r\n", hb_objGetClass(pItem)); 
      return; //invalid input
   }
      
   data = hb_itemArrayGet(pItem,ClassTestData.cText); 
   printf("Column \"%s\"",hb_itemGetC(data));
   data = hb_itemArrayGet(pItem,ClassTestData.nFormat);
   if(!HB_IS_NIL(data)) printf(" format:%i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,ClassTestData.nIndex);
   if(!HB_IS_NIL(data)) printf(" index:%i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,ClassTestData.nOrder);
   if(!HB_IS_NIL(data)) printf(" order:%i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,ClassTestData.nWidth);
   if(!HB_IS_NIL(data)) printf(" width %i",hb_itemGetNI(data));
   data = hb_itemArrayGet(pItem,ClassTestData.nWidthMin);
   if(!HB_IS_NIL(data)) printf(" min %i",hb_itemGetNI(data));
   printf("\r\n");   
   hb_ret();
}

#pragma ENDDUMP

 Here:
  • Create a class from C code
  • Write method code directly in C
  • Call harbour method from C code
I think it is a good example of how manipulate harbour object in C. 
Regards,
Antonino

Reply all
Reply to author
Forward
0 new messages