Ver Mensaje Individual
  #15  
Antiguo 25-07-2006
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Reputación: 22
Mick Va por buen camino
En el caso en particular que mencionas no importa el tipo de la variable, la funcion funcionaria igual poniendo cualquier tipo al puntero:

Código:
char *pantalla;
pointer pantalla;
PByteArray pantalla;
El problema se produce posteriormente cuando uno intenta trabajar con esos datos: Un PChar se entiende como una cadena de caracteres acabados en 0. Es decir el fin de la lista de caracteres esta marcado con el byte 0. Pero lo que esa funcion recoge es una zona de bytes que representa una captura de pantalla. Y en el medio de esos datos habra caracteres 0 pero no para indicar el fin de la captura de pantalla sino como un dato mas. Al asignarlo de cualquiera de las formas:

Código:
final:= pchar(datos); 
final:= datos;
Delphi dejará de copiar los caracteres a la variable final, en el momento que encuentre el primer valor CERO. DE modo que la variable "final" tendra solo una parte de la captura de pantalla.

Las variables string de delphi no tienen ese problema debido a que al principio de los datos guardan un contador con el tamaño de la cadena, lo que permite que la cadena de caracteres o bytes pueda contener cualquier valor incluido el cero. En cambio los PChar conceptualmente son iguales que los char * equivalentes de C, y el caracter 0 se utiliza como fin de cadena y no puede formar parte de los propios datos.

En ese caso hay que definir el tamaño del string primero y despues asignarlo con un bucle o mejor con una funcion que copie bloques de bytes ya que es mucho mas rapido. Por ejemplo:

Código:
 
SetLength(final,Longitud^); 
Move( datos^, final[1] , Longitud);
Aunque existe otro modo mas sencillo que ahorraria memoria y operaciones, y es pasar directamente un puntero al principio del string "final" y los datos ya estarian en su sitio despues de llamar a la funcion, es decir:

Código:
 
SetLength(final, TAMANO_MAXIMO_CAPTURA_PANTALLA); 
captura_pantalla(hclient, @final[1], longitud, tout); 
SetLength(final,longitud^);
Tenemos otra opcion que es no usar un String, por lo menos conceptualmente seria mas correcto no usar una variable String para trabajar con esos datos debido a que no representan una cadena de caracteres sino un array de bytes, en ese caso yo utilizaria un array de bytes o un PByteArray, para trabajar con esos datos.

Código:
 
uses Sysutils; 
... 
var 
longitud: integer; 
buffer:PByteArray; 

begin 
GetMem(buffer, TAMANO_MAXIMO_CAPTURA_PANTALLA); 
captura_pantalla(hclient, buffer, @longitud, tout); 
ReallocMem(buffer,longitud); 
.. 
.. 
// Hacemos lo que sea con buffer, 
// podemos acceder a los datos con buffer[indice] 
.. 
.. 
FreeMem(buffer);
end;
Saludos

Última edición por Mick fecha: 25-07-2006 a las 17:51:47.
Responder Con Cita