On Wed, 04 Feb 2009, Pritpal Bedi wrote:

Hi Pritpal

> HB_FUNC( WAPI_PRINTDLG )
> {
>    PRINTDLG *pd = hb_parc( 1 );  // structure WHEREEVER possible
>    ...
>    wapi_retstruct( pd );
> }

Passing C structures as string is also bad idea.
If we do not need support for direct updating C structure
members at .prg level then it will be enough to introduce
special type of GC pointer to hold all such structures with
basic type veryfication. Below I'm attaching modified code from
message I sent two days ago to xHGtk devel list. It address such
problem.


/* header file */

#include "hbapi.h"
#include "hbapiitm.h"
#include "hbapierr.h"
#include "hbstack.h"


#define HB_MEMSTRU_OSVERSIONINFO                1000001
#define HB_MEMSTRU_LOGFONT                      1000002

#define HB_ERR_MEMSTRU_NOT_MEM_BLOCK            4001
#define HB_ERR_MEMSTRU_WRONG_MEMSTRU_BLOCK      4002
#define HB_ERR_MEMSTRU_DESTROYED                4003

HB_EXTERN_BEGIN

extern PHB_ITEM hb_memstru_itemPut( PHB_ITEM pItem, void * pMemAddr, int iType 
);
extern void * hb_memstru_itemGet( PHB_ITEM pItem, int iType, BOOL fError );
extern void hb_memstru_ret( void * pMemAddr, int iType );
extern void * hb_memstru_param( int iParam, int iType, BOOL fError );

HB_EXTERN_END

/* end of header file */



typedef struct
{
   int      type;
   void *   mem;
}
HB_MEMSTRU_HOLDER, * PHB_MEMSTRU_HOLDER;

static HB_GARBAGE_FUNC( hb_memstru_destructor )
{
   PHB_MEMSTRU_HOLDER pStructHolder = ( PHB_MEMSTRU_HOLDER ) Cargo;

   if( pStructHolder->mem )
   {
      hb_xfree( pStructHolder->mem );
      pStructHolder->mem = NULL;
   }
}

PHB_ITEM hb_memstru_itemPut( PHB_ITEM pItem, void * pMemAddr, int iType )
{
   PHB_MEMSTRU_HOLDER pStructHolder;

   if( pItem )
   {
      if( HB_IS_COMPLEX( pItem ) )
         hb_itemClear( pItem );
   }
   else
      pItem = hb_itemNew( pItem );

   pStructHolder = ( PHB_MEMSTRU_HOLDER )
             hb_gcAlloc( sizeof( HB_MEMSTRU_HOLDER ), hb_memstru_destructor );
   pStructHolder->mem = pMemAddr;
   pStructHolder->type = iType;

   return hb_itemPutPtrGC( pItem, pStructHolder );
}

void * hb_memstru_itemGet( PHB_ITEM pItem, int iType, BOOL fError )
{
   PHB_MEMSTRU_HOLDER pStructHolder = ( PHB_MEMSTRU_HOLDER )
                               hb_itemGetPtrGC( pItem, hb_memstru_destructor );
   int iError = 0;

   if( !pStructHolder )
      iError = HB_ERR_MEMSTRU_NOT_MEM_BLOCK;
   else if( pStructHolder->type != iType )
      iError = HB_ERR_MEMSTRU_WRONG_MEMSTRU_BLOCK;
   else if( !pStructHolder->mem )
      iError = HB_ERR_MEMSTRU_DESTROYED;
   else
      return pStructHolder->mem;

   if( fError )
      hb_errRT_BASE_SubstR( EG_ARG, iError, NULL,
                            HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );

   return NULL;
}

void hb_memstru_ret( void * pMemAddr, int iType )
{
   hb_memstru_itemPut( hb_stackReturnItem(), pMemAddr, iType );
}

void * hb_memstru_param( int iParam, int iType, BOOL fError )
{
   return hb_memstru_itemGet( hb_param( iParam, HB_IT_POINTER ), iType, fError 
);
}

BOOL hb_memstru_store( void * pMemAddr, int iType, int iParam )
{
   PHB_ITEM pItem = hb_param( iParam, HB_IT_BYREF );
   if( !pItem )
      return FALSE;

   hb_memstru_itemPut( pItem, pMemAddr, iType );
   return TRUE;
}

/* end of code */

hb_memstru_*() functions can be used to pass structures between
C and .prg code.


HB_FUNC( WAPI_STRUCT_OSVERSIONINFO )
{
   OSVERSIONINFO * osvi;

   osvi = ( OSVERSIONINFO * ) memset( hb_xgrab( sizeof( OSVERSIONINFO ) ),
                                      0, sizeof( OSVERSIONINFO ) );
   osvi->dwOSVersionInfoSize = sizeof( OSVERSIONINFO );

   hb_memstru_ret( osvi, HB_MEMSTRU_OSVERSIONINFO );
}

HB_FUNC( WAPI_GETVERSIONEX )
{
   OSVERSIONINFO * osvi;

   osvi = ( OSVERSIONINFO * )
          hb_memstru_param( 1, HB_MEMSTRU_OSVERSIONINFO, TRUE );

   if( osvi )
      hb_retrl( GetVersionEx( osvi ) );
}


You can also define some general functions to access given structure
members if you will find it useful in some cases.

HB_FUNC( WAPI_MEMBER_OSVERSIONINFO )
{
   OSVERSIONINFO * osvi;
   const char * szMember;

   osvi = ( OSVERSIONINFO * )
          hb_memstru_param( 1, HB_MEMSTRU_OSVERSIONINFO, TRUE );
   szMember = hb_parc( 2 );
   if( osvi && szMember )
   {
      if( !strcmp( szMember, "dwMajorVersion" ) )
         hb_retnint( osvi->dwMajorVersion );
      elseif( !strcmp( szMember, "dwMinorVersion" ) )
         hb_retnint( osvi->dwMinorVersion );
      else if( !strcmp( szMember, "dwBuildNumber" ) )
         hb_retnint( osvi->dwBuildNumber );
      else if( !strcmp( szMember, "dwPlatformId" ) )
         hb_retnint( osvi->dwPlatformId );
      else if( !strcmp( szMember, "szCSDVersion" ) )
         wapi_rettstr( osvi->dwPlatformId );
      else if( ... )
         ...
      else
      {
         /* NIL for unknown members or RT error */
      }
   }
}


best regards,
Przemek
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to