Para Antonio... posible bug en Harbour

Para Antonio... posible bug en Harbour

Postby xmanuel » 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: Select all  Expand view


#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? :x :x :x :mrgreen: :mrgreen: :mrgreen: :mrgreen: :oops: :oops: :oops: :oops:
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 761
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Para Antonio... posible bug en Harbour

Postby Antonio Linares » Mon Aug 15, 2016 10:27 pm

Manu,

Puedes mostrar el código de bindParam() ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42068
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Para Antonio... posible bug en Harbour

Postby xmanuel » Tue Aug 16, 2016 6: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:

Code: Select all  Expand view

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 ) );
    }
}

 


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

Code: Select all  Expand view

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;
}
 


A ver si descubrimos porqué... :D
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 761
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Para Antonio... posible bug en Harbour

Postby Antonio Linares » Tue Aug 16, 2016 6: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42068
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Para Antonio... posible bug en Harbour

Postby Antonio Linares » Tue Aug 16, 2016 9:34 am

Prueba con:

pBind->pVariable = hb_gcLock( pVariable );

para liberar la variable:

hb_gcUnlock( pBind->pVariable );
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42068
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Para Antonio... posible bug en Harbour

Postby xmanuel » Tue Aug 16, 2016 12:29 pm

:roll: 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:
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 761
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Para Antonio... posible bug en Harbour

Postby Antonio Linares » Tue Aug 16, 2016 3: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42068
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Para Antonio... posible bug en Harbour

Postby xmanuel » Tue Aug 16, 2016 8:43 pm

Antonio antes de nada volverte a dar las gracias por tu tiempo...

Aquí tienes un ejemplo simplon
Parte PRG:

Code: Select all  Expand view


 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
Code: Select all  Expand view


#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 );
    }
}

 


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" :roll:
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 761
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Para Antonio... posible bug en Harbour

Postby Antonio Linares » Thu Aug 18, 2016 4: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42068
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Para Antonio... posible bug en Harbour

Postby xmanuel » Thu Aug 18, 2016 8: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: Select all  Expand view

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: Select all  Expand view

 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: Select all  Expand view

 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
xmanuel
 
Posts: 761
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla

Re: Para Antonio... posible bug en Harbour

Postby Antonio Linares » Fri Aug 19, 2016 3: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
User avatar
Antonio Linares
Site Admin
 
Posts: 42068
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Para Antonio... posible bug en Harbour

Postby xmanuel » Mon Aug 22, 2016 6:12 pm

OK, ya lo he puesto.
Aún así s puedes miralo a ver si conseguimos algo :?
______________________________________________________________________________
Sevilla - Andalucía
xmanuel
 
Posts: 761
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 15 guests