Cuando trabajamos con Velneo y necesitamos hacer una llamada a una dll que retorna una cadena (string) nos encontramos con la tesitura de como liberar el espacio de memoria alojada para la cadena en cuestión en la dll. Veamos un método, que no el único, para liberar esa memoria. Este método sólo va a servir para las dlls que creemos nosotros, ya que debemos añadir un par de funciones extra.
El escenario
Veamos el escenario que vamos a utilizar para poner en funcionamiento nuestra técnica. Tenemos un mapa en Velneo desde el que necesitamos llamar a una función de una dll que debe retornar una cadena de caracteres (un char*). La cadena no tiene una longitud fija, por lo que nos interesa alojar el espacio en memoria en la propia función de la dll y retornar la cadena completa.
La solución
Lo primero que se nos ocurre es hacer una función que retorne un char* y recogerlo en Velneo, pero tenemos que ser conscientes de que ese espacio en memoria no se a a liberar, por lo que estamos dejando un motón de basura.
Lo que vamos a hacer es retornar el puntero a ese char*, y nos creamos dos funciones extra en la dll, getString y freeString. El código en C sería algo así:
unsigned long test(int variables, ...)
{
char* cadena = (char *) malloc(1024);
// Procesamos la cadena y retornamos su direccion de memoria
return (unsigned long)cadena;
}
char* getString(unsigned long address)
{ // Retornamos el contenido de esa dirección
return (char*) address;
}
void freeString(unsigned long address)
{ // Liberamos esa dirección de memoria
free((void *)address);
}
Desde Velneo haremos las llamadas en el siguiente orden:
Set ptr_cadena, testDll.test('variables')
// En esta variable local tenemos la direccion de memoria. Obtengamos el contenido
Set cadena, testDll.getString('ptr_cadena')
// Liberemos ese espacio reservado
Set void, testDll.freeString('ptr_cadena')
Con esta sencilla artimaña nos aseguramos de que no quede espacio en memoria ocupada sin liberar.
Esta es la opción que yo utilizo. Si usas algún otro truco, aprovecha para compartirlo con la comunidad escribiendo un comentario.



Si utilizas C++ puedes usar la Clase String para estas lides.
char* __stdcall Fichero2Cadena(const char* rutaFichero){
int iFileHandle;
int iFileLength;
char *buffer;
AnsiString strTemp;
try{
iFileHandle = FileOpen(rutaFichero, fmOpenRead);
iFileLength = FileSeek(iFileHandle,0,2);
FileSeek(iFileHandle,0,0);
buffer = (char*)malloc((iFileLength+1)*sizeof(char));
FileRead(iFileHandle, buffer, iFileLength);
FileClose(iFileHandle);
// *************************************************************
// Asignamos a un AnsiString el buffer para así poder liberarlo.
// *************************************************************
strTemp = buffer;
free(buffer);
return (char*)strTemp.c_str();
}
catch(Exception &e){
free(buffer);
return (char*)e.Message.c_str();
}
}
Efectivamente parece un sistema mucho más sencillo. Lo que no tengo tan claro es que la memoria alojada para strTemp sea liberada. Me lo puedes confirmar?
Hola gVera.
Ya quisiera yo que mi conocimiento de C/C++ fuera lo suficientemente sólido como para hacer cualquier aseveración a prueba de bombas….
Por lo que yo sé, el tipo de clase String declarado dentro de una función se libera al terminar ésta.
Un saludo. Roberto.