Devolver una Matriz o Array desde una función en C

Devolver una Matriz o Array desde una función en C

Postby Verhoven » Mon May 06, 2013 9:40 am

Debido a requerir bastante velocidad en un proceso estoy tratando de implementar una función en C que necesito que me devuelva una matriz de caracteres.
He buscado algún ejemplo parecido pero no logro encontrarlo.
Adjunto el código con el que estoy probando, aunque no funciona, para ver si alguien puede decir cómo hacerlo o poner algún ejemplo.
Gracias de antemano.

Code: Select all  Expand view  RUN
#pragma BEGINDUMP
#include "windows.h"
#include "hbapi.h"
#include "string.h"

HB_FUNC( DEVUELVEMATRIZ )
{
   LPSTR szTitle = "Nuevo valor";
   //LPSTR szMsg = "Hasta Aquí llega";

   PHB_ITEM pArray;

   char cadena[] = "STATES 1:2|200,2,1:2|201,2,1:7923|202,2,1:5568|203,2,1:1423|204,2,1:1423|205,2,1:1|206,2,1:1|208,2,1:1|209,2,1:17|210,2,1:1|213,2,1:A2DED32F|";
 
   char *elemento;

   elemento = [b]strtok[/b](cadena," |");

   pArray = hb_itemArrayNew(0);

   while (elemento != NULL)
   {
      //printf("%s\n",elemento);
      MessageBox( GetActiveWindow(), elemento, szTitle, 0x40 );

      hb_arrayAddForward(pArray,( PHB_ITEM ) elemento );
      elemento = strtok(NULL," |");
   }
   
   /* Manejo de la matriz dentro de la función en C.
   for(i=1;i<=13;i++)
   {
     MessageBox( GetActiveWindow(), pArray+i-1, szTitle, 0x40 );
   }      
   */

   
  //Devolver matriz al prg:
   hb_itemReturn( pArray );

   //return pArray;
}
#pragma ENDDUMP
Verhoven
 
Posts: 522
Joined: Sun Oct 09, 2005 7:23 pm

Re: Devolver una Matriz o Array desde una función en C

Postby Antonio Linares » Mon May 06, 2013 10:46 am

Usa la función hb_ATokens( cTuCadena, "|" )

Tienes varios errores en tu código, si quieres te los comento.
regards, saludos

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

Re: Devolver una Matriz o Array desde una función en C

Postby Verhoven » Mon May 06, 2013 11:43 am

Gracias Antonio por contestar.
He intentado utilizar esa función que dices pero el problema que tiene es que solo "filtra" mediante un único caracter y yo necesito que sean al menos 3 cualesquiera de ellos, cosa que si admite esa función de C llamada strtok, si te fijas bien, en esa función pongo dos caracteres para el filtrado, el espacio y el símbolo |, por eso tiene dos caracteres an el segundo parámetro: strtok(cadena," |").

Por supuesto que te agradezco que me corrijas los errores (algunos serán horrores) que hayas encontrado.

Por cierto, he conseguido un ejemplo para devolver una matriz numérica desde el código C al PRG con el siguiente código:

Code: Select all  Expand view  RUN
  hb_reta( 3 );
   hb_stornl(  1, -1, 1 );
   hb_stornl( 12, -1, 2 );
   hb_stornl( 13, -1, 3 );


Pero no tengo mucha seguridad en lo que he hecho porque no tengo la documentación de ese tipo de funciones hb_stor... que parece que son necesarias para este asunto.
Verhoven
 
Posts: 522
Joined: Sun Oct 09, 2005 7:23 pm

Re: Devolver una Matriz o Array desde una función en C

Postby Antonio Linares » Mon May 06, 2013 1:15 pm

Prueba asi:

Code: Select all  Expand view  RUN
HB_FUNC( DEVUELVEMATRIZ )
{
   LPSTR szTitle = "Nuevo valor";
   //LPSTR szMsg = "Hasta Aquí llega";

   PHB_ITEM pArray;

   char cadena[] = "STATES 1:2|200,2,1:2|201,2,1:7923|202,2,1:5568|203,2,1:1423|204,2,1:1423|205,2,1:1|206,2,1:1|208,2,1:1|209,2,1:17|210,2,1:1|213,2,1:A2DED32F|";
 
   char *elemento;

   elemento = [b]strtok[/b](cadena," |");

   pArray = hb_itemArrayNew( 0 );

   while (elemento != NULL)
   {
      PHB_ITEM pItem = hb_itemPutC( NULL, elemento );

      //printf("%s\n",elemento);
      MessageBox( GetActiveWindow(), elemento, szTitle, 0x40 );

      hb_arrayAddForward( pArray,( PHB_ITEM ) pItem );
      hb_itemRelease( pItem );

      elemento = strtok(NULL," |");
   }
   
   /* Manejo de la matriz dentro de la función en C.
   for(i=1;i<=13;i++)
   {
     MessageBox( GetActiveWindow(), pArray+i-1, szTitle, 0x40 );
   }      
   */

   
  //Devolver matriz al prg:
   hb_itemReturn( pArray );

   //return pArray;
}
regards, saludos

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

Re: Devolver una Matriz o Array desde una función en C

Postby Verhoven » Mon May 06, 2013 3:00 pm

Ha funcionado prefectamente.
Muchas gracias Antonio.
Verhoven
 
Posts: 522
Joined: Sun Oct 09, 2005 7:23 pm

Re: Devolver una Matriz o Array desde una función en C

Postby Antonio Linares » Mon May 06, 2013 5:48 pm

Prueba a añadir esta línea al final y comprueba si sigue funcionando bien, gracias:

hb_itemRelease( pArray );
regards, saludos

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

Re: Devolver una Matriz o Array desde una función en C

Postby Verhoven » Tue May 07, 2013 10:29 am

Va perfecto.
He modificado el código para poderle pasar como parámetro una cadena.
Como strtok modifica el parámetro que se le pasa hago antes una copia para trabajar con ella.
Adjunto código a ver si te parece que está bien y por si a alguien más le viene bien.

Code: Select all  Expand view  RUN

#pragma BEGINDUMP

#include "windows.h"
#include "hbapi.h"
#include "string.h"

HB_FUNC( DEVUELVEMATRIZ )
{
   PHB_ITEM pArray;

   size_t nSize = 0;
   char *cadena;    // Contendrá una copia para trabajar de la cadena pasada a la función
   char *elemento;
       
   nSize = strlen( hb_parc( 1 ) )+1; //Suma uno para incluir el caracter de final de cadena='\0'
   cadena=(char *)malloc(nSize);     // Reserva la memoria para la variable: cadena.
   //memset(cadena,NULL,nSize);      // Inecesario porque cadena será igual que hb_parc( 1 )
       
   memcpy( ( void * ) cadena, ( void * ) hb_parc( 1 ), nSize );

   elemento = strtok(cadena," |");

   pArray = hb_itemArrayNew( 0 );

   while (elemento != NULL)
       {
          PHB_ITEM pItem = hb_itemPutC( NULL, elemento );

          //printf("%s\n",elemento);
          //MessageBox( GetActiveWindow(), elemento, "elemento", 0x40 );

          hb_arrayAddForward( pArray,( PHB_ITEM ) pItem );
          hb_itemRelease( pItem );

          elemento = strtok(NULL," |");
       }
       
   free(cadena);  //Libera la memoria reservada para la variable: cadena
   //Devolver matriz al prg:
   hb_itemReturn( pArray );
   hb_itemRelease( pArray );
}
 
Verhoven
 
Posts: 522
Joined: Sun Oct 09, 2005 7:23 pm

Re: Devolver una Matriz o Array desde una función en C

Postby Antonio Linares » Tue May 07, 2013 11:13 am

En vez de usar malloc() y free() usa hb_xgrab() y hb_xfree() de Harbour
regards, saludos

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

Re: Devolver una Matriz o Array desde una función en C

Postby Verhoven » Tue May 07, 2013 5:56 pm

Tu consejo me dejas con algunas dudas de llamémosle principios, como:
¿ Porqué es mejor utilizar las funciones de Harbour que las standard de C ?.
¿ No sería más portable el código "cuanto más en C" esté ?, al fin y al cabo, Harbour lo pasa primero a C para que luego el BCC o cualquier otro lo pasen a obj.
Verhoven
 
Posts: 522
Joined: Sun Oct 09, 2005 7:23 pm

Re: Devolver una Matriz o Array desde una función en C

Postby Antonio Linares » Tue May 07, 2013 6:50 pm

Harbour (lo aprendimos con Clipper) cuida de la robustez de la aplicación y para esto evita posible errores.

hb_xgrab() llama a malloc() pero comprueba que no se le pase un valor cero, tambien controla que el resultado no sea nulo, y ademas anota en un sistema propio de Harbour datos acerca del bloque de memoria solicitado, para que si la memoria al final no se libera, lo sepamos y asi se pueda corregir.

Como ves, es una capa muy delgada y robusta sobre funciones propias de C, para evitar errores que harian que nuestra aplicación generase un GPF (algo muy tipico en aplicaciones C puras) :-)

De hecho, la filosofia de la maquina virtual de Harbour es precisamente la misma: evitar errores, controlar el flujo de la aplicación, darle robustez. La robustez por la que Clipper siempre ha sido famoso, sin usar excesivas capas que lo enlentecerian :-)
regards, saludos

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

Re: Devolver una Matriz o Array desde una función en C

Postby Verhoven » Wed May 08, 2013 7:44 am

Desde luego que esos son ARGUMENTOS y con ello, me parece oportuno reconocer que es un placer leer tus explicaciones, siempre se aprende algo.
Mi más sincero agradecimiento.

Lástima que no tengamos una documentación mejor de Harbour para sacarle mejor provecho.
Verhoven
 
Posts: 522
Joined: Sun Oct 09, 2005 7:23 pm

Re: Devolver una Matriz o Array desde una función en C

Postby Antonio Linares » Wed May 08, 2013 10:18 am

Nosotros ofrecemos esta documentación de Harbour, aunque no es la más completa ni cubre todo:

http://www.fivetechsoft.com/harbour-docs/harbour.html

De todas formas, acabo de preguntar en la lista de desarrollo de Harbour, cual sería el sitio en donde esté la mejor documentación de Harbour disponible:

https://groups.google.com/forum/?fromgroups=#!topic/harbour-devel/ddUuezv7sgA
regards, saludos

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


Return to FiveWin para Harbour/xHarbour

Who is online

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