Page 1 of 1

Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Mon Nov 25, 2013 1:39 pm
by xmanuel
Buenas a todos.
A ver si alguien sabe decirme como acceder a la estructura interna de HB_ITEM en Harbour (no en xHarbour).
Concrétamente quiero acceder a la dirección de:
myItem->item.asString.length // OJO, no al valor si no a la dirección.

Como ejemplo:
myItem->item.asString.value;

puedo acceder así:
char * miPuntero = myItem->item.asString.value;
o con la función:
char * miPuntero = hb_itemGetCPtr( myItem ); // Esta es la aconsejable

Pero para myItem->item.asString.length, cómo?
Hay alguna función que haga lo mismo que hb_itemGetCPtr( myIyem ) pero para myItem->item.asString.length?

:D :mrgreen: :( :shock: :P :twisted: :?: :idea: :arrow:

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Mon Nov 25, 2013 3:05 pm
by Daniel Garcia-Gil
Manuel

Harbour trabaja internamente por omision de forma protegida para que no puedas hacer eso, pero eso no implica que no exista forma de hacerlo

debes compilar con el define "_HB_API_INTERNAL_"

te dejo un ejemplo y la linea que de comando que uso para ejecutarlo

Code: Select all  Expand view

function  main()

    prueba( "hello world!" )

return nil

#pragma BEGINDUMP
#include <hbapi.h>
#include <hbapiitm.h>

HB_FUNC(PRUEBA)
{
    PHB_ITEM miPuntero = hb_itemNew(NULL);

    const char * c = hb_parc(1);

    hb_itemPutC( miPuntero, c );

    printf("%s %d", miPuntero->item.asString.value, miPuntero->item.asString.length);

    hb_itemRelease( miPuntero );

}

#pragma ENDDUMP
 


linea de comando: hbmk2 test -cflag=-D_HB_API_INTERNAL_

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Mon Nov 25, 2013 7:34 pm
by xmanuel
Muchas gracias Daniel...
Quería evitar eso precisamente.

si existiera una función que devolviera la dirección sería lo ideal para mí:

...
return &miPuntero->item.asString.length;

Se te ocurre algo? :mrgreen:

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Mon Nov 25, 2013 8:29 pm
by Daniel Garcia-Gil
Manuel

podrias hacerlo asi...

Code: Select all  Expand view
function  main()

    prueba( "hello world!" )

return nil

#pragma BEGINDUMP
#include <hbapi.h>
#include <hbapiitm.h>

HB_FUNC(PRUEBA)
{
    PHB_ITEM miPuntero = hb_itemNew(NULL);

    const char * c = hb_parc(1);

    int * i;

    hb_itemPutC( miPuntero, c );

    i = &((int)(miPuntero->item.asString.length));

    printf("%s %d", miPuntero->item.asString.value, *i);

    hb_itemRelease( miPuntero );

}

#pragma ENDDUMP

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Mon Nov 25, 2013 8:49 pm
by xmanuel
Ya Daniel, pero lo que quiero es evitar usar la estructura ITEM.
Lo que quiero es usar una función al estilo hb_itemGetCPtr( myItem ) pero para el puntero a myItem->item.asString.length ya así mo tener que ir en contra de las recomendaciones del equipo de Harbour.

Mira:
//--------------------------------------
HB_SIZE hb_itemGetCLen( PHB_ITEM pItem )
{
HB_TRACE( HB_TR_DEBUG, ( "hb_itemGetCLen(%p)", pItem ) );

if( pItem && HB_IS_STRING( pItem ) )
return pItem->item.asString.length;
else
return 0;
}

//--------------------------------------
Pues en vez de eso me gustaria que en las funciones del ITEM API hubiera una que devuelva el puntero y no el valor. Así no tendría que usar la directiva no recomendada _HB_API_INTERNAL_

long * hb_itemGetCPtrLen( PHB_ITEM pItem )
{
if( pItem && HB_IS_STRING( pItem ) )
return &pItem->item.asString.length;
else
return NULL;
}

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

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Wed Nov 27, 2013 10:27 am
by xmanuel
Daniel si conoces a alguien del equipo de harbour y de xharbour podrías pedirle que incluyan la función?

Code: Select all  Expand view

HB_SIZE * hb_itemGetCPtrLen( PHB_ITEM pItem )
{
    if( pItem && HB_IS_STRING( pItem ) )
    {
          return &pItem->item.asString.length;
    }
    else
    {
         return NULL;
    }
}
 


Podrás? :D

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Wed Nov 27, 2013 7:48 pm
by xmanuel
Olvidate Daniel.
Escribí a Przemek y me ha dado una amplia explicación de porqué no está ni estará :-(

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Wed Nov 27, 2013 9:45 pm
by Daniel Garcia-Gil
Manuel

por curiosidad cual es la explicacion que te dieron?

Re: Acceder a la estructura HB_ITEM en Harbour. Daniel o Antonio

PostPosted: Fri Nov 29, 2013 7:30 pm
by xmanuel
Jajaja te pica la curiosidad no?

Te la transcribo tal cual, ya sabes que Przemek se esplaya:

There are few serious problems with such function.
It operates on pointer to item body which may change if some
other code change the item value. In such case modifying the
value at pointer address will corrupt new item and maybe HVM
HVM expect that all strings are CHR(0) ended in many different
places. Strings without this condition may cause HVM crash.
But if you try to update string body then it may corrupt many
other string items two. String items are shared and copy on write
mechanism is used. If you change one string then you will also
change all other string items which share item value. You cannot
change string item body or string item length because it may
effect more then one item. In the worst case you will overwrite
one of internal buffers used for shared string values changing
all strings which may store such value even if they will be
created in the future, i.e. all one byte strings are pointers
to execatly the same memory area. Constant strings are pointers
to PCODE so if you change them then PCODE is changed too and
will give different results executed next time.
Additionally if you try to write to static readonly buffer on
systems with hardware readonly memory protection it will cuase
GPF. There are also any other bad side effects.
I cannot imagine where such function can be safely used without
risk of internal HVM corruption. IMHO you should rethink what
you are trying to do and how to avoid manipulations in HVM
intenral area.

best regards,
Przemek