FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Para Antonio... posible bug en Harbour
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Para Antonio... posible bug en Harbour
Posted: Mon Aug 15, 2016 10:09 AM
Sé que no es aquí sitio más apropiado pero como mi inglés es pésimo no quiero escribir en la lista...

Tengo una funcion en C que básicamente recibe un parametro por referencia y lo guarda en una estructura.

Luego con un GET acepto el valor desde un PRG pero, he aquí el problema, cuando la variable la declaro en el PRG como LOCAL el valor no es visible en C, en cambio cuando lo hago como STATIC sí.
He averiguado que si antes del GET pongo esto _GET_( niVar, "niVar" ) si funciona bien aunque sea local. Por lo que deduzco que el GET hace algo por que hacer perder la referencia a la variable.
Code (fw): Select all Collapse
#include "hdo.ch"
#include "InKey.ch"

//------------------------------------------------------------------------------

procedure main()

    static nSocIni, nSocFin  // Con local no funciona, static si... porque?     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    local oDb, oStmt, oCur, e
    local cDb := "agenda.db"
    local cTabla := "socios"
    local cSql := "SELECT * FROM " + cTabla + " WHERE clavesocio BETWEEN ? AND ? ;"
    local getlist := {}
            
    nSocIni := nSocFin := 0

    cls

    oDb := THDO():new( "sqlite" )

    oDb:setAttribute( ATTR_ERRMODE, .t. )

    if oDb:connect( cDb )
        TRY
            oStmt := oDb:prepare( cSql )  // Prepara la sentencia y crea el objeto oStmt

            oStmt:bindParam( 1, @nSocIni )   // <<<<<<<<<<<<<<<<<<<<<<<<<<< AQUI LAS METO EN LA ESTRUCTURA EN C
            oStmt:bindParam( 2, @nSocFin )  // <<<<<<<<<<<<<<<<<<<<<<<<<<< AQUI LAS METO EN LA ESTRUCTURA EN C

            @ maxrow(), 00 say "Presiona <INTRO> para selecionar rangos o <ESC> para salir..."

            while inkey( 0 ) != K_ESC

                cls

                @ 02, 02 say "Entrada de datos:"
                @ 04, 02 say "Entre rango inicial:" get nSocIni picture "@K9"
                @ 05, 02 say "Entre rango final..:" get nSocFin picture "@K9" valid validaRango( nSocIni, nSocFin )
    
                read
                
                if lastkey() != K_ESC .and. updated()

                    oStmt:execute() // Ejecuta la sentencia     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< AQUI USO LAS VARIABLES PERO EN C PERO SOLO PASA EL VALOR SI SON STATIC O LAS ASIGNO SIN EL GETSYSTEM

                    // Creamos un cursor local (navigator) como un hash table
                    oCur := THashCursor():new( oStmt:fetchAll( FETCH_HASH ) )

                    cls

                    @ 00, 00 say "Resultado de la consulta -> " + hb_ntos( oStmt:rowCount() ) + " registros:" color "W+/R"
                    @ maxrow(), 00 say "<ESC> para volver al menu..." color "W+/R"

                    if oCur:reccount() > 0
                        miBrwCursor( oCur, 1, 0, maxrow() - 1, maxcol() )
                    else
                        msg( "No hay registros en ese rango" )
                    endif

                    oCur:free()
                else
                    msg( "Nada que hacer..." )
                endif

                cls
                @ maxrow(), 00 say "Presiona <INTRO> para selecionar rangos o <ESC> para salir..."
            end
            
        CATCH e
            eval( errorblock(), e )
        FINALLY
            if oStmt:className() == "THDOSTATEMENT"
                oStmt:free()
            endif
            msg( "Se acabo" )
        end

    endif

    oDb:disconnect()

return

//------------------------------------------------------------------------------


Qué puede ser? :-) :-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
______________________________________________________________________________

Sevilla - Andalucía
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Mon Aug 15, 2016 10:27 PM

Manu,

Puedes mostrar el código de bindParam() ?

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Tue Aug 16, 2016 06:01 AM
Gracias Antonio, por supuesto que si, pero me reitero cuando lo asigno directamente aunque sea local funciona
así funciona nSocIni := 5 es cuando lo paso por el GET cuando deja de funcionar salvo que la declare como static...

Aquí está el c´digo del métod BINDPARAM:

<div class="c" id="{CB}" style="font-family: monospace;">
HB_METHOD( THDOSTATEMENT_BINDPARAM )
{
    PHDOSTMT stmt = hb_getStmt();

    if( stmt )
    {
        STMT_BINDPARAM( stmt, hb_param( 1, HB_IT_NUMERIC | HB_IT_STRING ),
                        hb_param( 2, HB_IT_BYREF ), hb_parni( 3 ), hb_parni( 4 ) );
    }
}

 </div>


Y aquí está el código de la función bindParam()

<div class="c" id="{CB}" style="font-family: monospace;">
static HB_ERRCODE bindParam( PHDOSTMT stmt, PHB_ITEM pParam, PHB_ITEM pVariable, HB_USHORT uiType, HB_SIZE nLen )
{
    if( pParam && pVariable )
    {
        /* Si no existe la lista de parametros la creamos y la inicializamos */
        if( !stmt->pListParam )
        {
            stmt->pListParam = ( PHDO_LISTBIND ) hb_xalloc( sizeof( HDO_LISTBIND ) );

            if( stmt->pListParam )
            {
                stmt->pListParam->uiCount = 0;
                stmt->pListParam->pListBind = NULL;
            }
            else
            {
                hdo_throwException( stmt->hdo, HDO_NOTMEMPAR, NULL );
                return HB_FAILURE;
            }
        }

        if( stmt->pListParam )
        {
            PHDO_BIND pBind = ( PHDO_BIND ) hb_xalloc( sizeof( HDO_BIND ) );

            if( pBind )
            {
                HB_UINT i = stmt->pListParam->uiCount++;

                stmt->pListParam->pListBind = ( PHDO_BIND * ) hb_xrealloc( stmt->pListParam->pListBind,
                                          sizeof( PHDO_BIND ) * stmt->pListParam->uiCount );
                pBind->pId = hb_itemNew( pParam );
                pBind->pVariable = pVariable;
                pBind->uiType = uiType ? uiType : HB_ITEM_TYPE( pVariable );
                pBind->nMaxLen = nLen;

                *( stmt->pListParam->pListBind + i ) = pBind;

                return HB_SUCCESS;
            }
            else
            {
                hdo_throwException( stmt->hdo, HDO_NOTMEMPAR, NULL );
                return HB_FAILURE;
            }
        }
    }

    hdo_throwException( stmt->hdo, !pVariable ? HDO_NOTREFER : HDO_NOTINTORSTR, NULL );
    return HB_FAILURE;
}
 </div>


A ver si descubrimos porqué... :-)
______________________________________________________________________________

Sevilla - Andalucía
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Tue Aug 16, 2016 06:37 AM

Si almacenas una variable a bajo nivel, tienes que bloquearla para que el recolector de basura no la destruya.

Eso explicaría porque las static funcionan y no las locales.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Tue Aug 16, 2016 09:34 AM

Prueba con:

pBind->pVariable = hb_gcLock( pVariable );

para liberar la variable:

hb_gcUnlock( pBind->pVariable );

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Tue Aug 16, 2016 12:29 PM

me temo que de eso no es ya lo he probado.
Te recuerdo que si en vez de tomar el valor del GET se lo asigno directamente SÍ funciona.
Además pVariable es un PHB_ITEM pasado por referencia con lo que se supone que el ITEMAPI lo habrá hecho automáticamente.

Ya que estás Antonio me podrías decir para qué vale y cuándo se debe usar la función "hb_itemUnRef()" :D

Muchas gracias por tu tiempo :oops:

:roll:

______________________________________________________________________________

Sevilla - Andalucía
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Tue Aug 16, 2016 03:47 PM

Manu,

> Te recuerdo que si en vez de tomar el valor del GET se lo asigno directamente SÍ funciona.

Puedes proporcionar un ejemplo auto contenido que no use ninguna librería externa y
que reproduzca el problema ?

> Además pVariable es un PHB_ITEM pasado por referencia con lo que se supone que el ITEMAPI lo habrá hecho automáticamente.

El que las locales fallen es un caso típìco de que la local ha sido destruida. El que se pase por referencia
no creo que haga que la variable se bloquee. Una vez sales de una función, las locales se destruyen.

> Ya que estás Antonio me podrías decir para qué vale y cuándo se debe usar la función "hb_itemUnRef()"

/ De-references item passed by the reference /

PHB_ITEM hb_itemUnRef( PHB_ITEM pItem )

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Tue Aug 16, 2016 08:43 PM
Antonio antes de nada volverte a dar las gracias por tu tiempo...

Aquí tienes un ejemplo simplon
Parte PRG:

Code (fw): Select all Collapse
 procedure main()
 
    local getlist := {}
    local parametro := 0 // Solo funciona si se asigna directamente
    //static parametro := 0  // Asi funciona siempre
    local hSt := creaSt()
    
    bindParam( hSt, @parametro )
    
    cls
    
    // Desmarca la que preceda entre los dos casos:
    
    // Caso (1) Asignacion directa
    // parametro := 100  // Asignado directamente funciona siempre

    // Caso (2) Solo funciona si se declara la variable "parametro" como static
    @ 05, 10 SAY "Introduce el parametro:" GET parametro PICTURE "@K9"
    READ
    
    execute( hSt )
    
    Inkey( 100 )
    
return


Parte de C
<div class="c" id="{CB}" style="font-family: monospace;">

#include "item.api"
#include <windows.h>

typedef struct miStructura
{
    HB_USHORT uiCount;
    PHB_ITEM  pVariable;                
} MIESTR, *PMIESTR;

HB_FUNC( MYMSG )
{
   MessageBox( NULL, hb_parc( 1 ), "Atencion",
                         MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL );
}


/*
 * Crea una estructura vacia
 */
 
HB_FUNC( CREAST ) 
{
    PMIESTR lc = ( PMIESTR ) hb_xalloc( sizeof( MIESTR ) );
    
    if( lc )
    {
        lc->uiCount = 0;
        
        hb_retptr( lc );
    }
    else
    {
        hb_ret();
        MessageBox( NULL, "No se ha creado la estructura", "Atencion", MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL );
    }
}

HB_FUNC( BINDPARAM ) 
{
    PMIESTR lc = ( PMIESTR ) hb_parptr( 1 );
    
    if( lc )
    {
        PHB_ITEM  pVariable = hb_param( 2, HB_IT_BYREF );
        
        if( pVariable )
        {
            lc->pVariable = pVariable;
            lc->uiCount++;
        }
        else
        {
            MessageBox( NULL, "Parametro 2 no se paso por referencia", "Atencion", MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL );
        }
    }
    else
    {
        MessageBox( NULL, "Parametro 1 incorrecto", "Atencion", MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL );
    }
}

HB_FUNC( EXECUTE ) 
{
    PMIESTR lc = ( PMIESTR ) hb_parptr( 1 );
    
    if( lc )
    {
       char szBuffer[3 ];

        wsprintf( szBuffer, "%d", hb_itemGetNI( lc->pVariable ) );

        MessageBox( NULL, szBuffer, "Atencion", MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL );
    }
    else
    {
        MessageBox( NULL, "Parametro 1 incorrecto", "Atencion", MB_OK | MB_ICONINFORMATION | MB_SYSTEMMODAL );
    }
}

 </div>


Si la variable "parametro" se declara como local solo funciona si se asigna directamente. Prueba a comentar la parte del GET "caso 2"
Si la variable "parametro" se declara como static funciona con el "caso 1" y con la parte del GET "caso 2"

A ver si puedes ver el problemilla y como solucionarlo usando el GET y sin "trucos" :-)
______________________________________________________________________________

Sevilla - Andalucía
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Thu Aug 18, 2016 04:54 PM

A mi me aparece siempre un cero mostrado desde tu función Execute()

No entiendo bien lo que quieres hacer

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Thu Aug 18, 2016 08:22 PM
Lo que tendría que salir es el valor introducido en el get, pero desde C, lo que pretendo es que cuando introduzca un valor desde PRG sin necesidad de pasarlo como un parámetro en una función en C ya sea visible. Y ya te digo, funciona siempre que la variable en cuestión no pase por un GET, por eso creo que es un fallo del getSystem de Harbour que no respeta la referencia original...

Mira este trozo de codigo:
Code (fw): Select all Collapse
 
procedure main()
 
    local getlist := {}
    local parametro := 0 // Solo funciona si se asigna directamente <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //static parametro := 0  // Asi funciona siempre <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    local hSt := creaSt()

comenta el local y descomenta el static:
Code (fw): Select all Collapse
 procedure main()
 
    local getlist := {}
    //local parametro := 0 // Solo funciona si se asigna directamente
    static parametro := 0  // Asi funciona siempre
    local hSt := creaSt()


y prueba ahora.

ATENCION OTRA COSA:
Además prueba a poner lo que te indico aunque la variable parametro sea local si funciona

Code (fw): Select all Collapse
 procedure main()
 
    local getlist := {}
    local parametro := 0 // Solo funciona si se asigna directamente
    //static parametro := 0  // Asi funciona siempre
    local hSt := creaSt()

    _GET_( parametro , "parametro " )  // <<<<<< Si pongo esto también funciona, OJO por encima de la función bindParam, por eso pienso que se pierde la referencia cuando pasa por el get

    bindParam( hSt, @parametro )
   
    cls
   
    // Desmarca la que preceda entre los dos casos:
   
    // Caso (1) Asignacion directa
    // parametro := 100  // Asignado directamente funciona siempre

    // Caso (2) Solo funciona si se declara la variable "parametro" como static
    @ 05, 10 SAY "Introduce el parametro:" GET parametro PICTURE "@K9"
    READ
   
    execute( hSt )
   
    Inkey( 100 )
   
return
______________________________________________________________________________

Sevilla - Andalucía
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Fri Aug 19, 2016 03:58 PM

Manuel,

Lo suyo es que lo comentes en la lista de usuarios de Harbour

Con que pongas un ejemplo es suficiente

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 817
Joined: Sun Jun 15, 2008 07:47 PM
Re: Para Antonio... posible bug en Harbour
Posted: Mon Aug 22, 2016 06:12 PM

OK, ya lo he puesto.
Aún así s puedes miralo a ver si conseguimos algo :?

______________________________________________________________________________

Sevilla - Andalucía

Continue the discussion