Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   pasar contenido de pchar a string (https://www.clubdelphi.com/foros/showthread.php?t=33938)

coletaun 21-07-2006 01:46:42

pasar contenido de pchar a string
 
hola a todos.

Despues de ejecutar un funcion y obeter un puntero pchar de un determinao array, tengo que pasar estos datos a un string para poder tratarlos. ¿alguien sabe como hacer ésto?

muchas gracias.

nemesio 21-07-2006 01:56:41

Prueba esto a ver si es lo que quieres.

Código Delphi [-]
for I:=1 to Max do
begin
   cString[i]:=cChar[i];
end;

Suerte.

coletaun 21-07-2006 02:38:01

max?
 
ok, con esto paso los datos de mi variable:

datos: pchar;
final :string;

paso los datos de "datos" a final d eesta foram. ¿y el max seria el numero de caracters contenidos en el puntero datos?

gracias

nemesio 21-07-2006 02:42:27

Si, max es la cantidad de caracteres.

Suerte.

Mick 21-07-2006 03:58:14

Hombre, la forma normal es simplemente asignarlos y listo, hacer un bucle aunque valido (el del ejemplo habria que corregirlo ya que no se fija el tamaño del string asi que dara error) es un poco matar moscas a cañonazos ademas de mas lento.

Código:

var
  datos: pchar;
  final :string;

begin
    final:= datos;
end;


Sudamericano 21-07-2006 04:29:35

mejorando el ejemplo anterior, con eso te funcionara correctamente
Código Delphi [-]

var
  datos: pchar;
  final :string;

begin
    final:= pchar(datos);
end;

Mick 21-07-2006 04:51:15

Hacer un cast a PChar(datos) es una redundancia debido a que datos YA es de tipo PChar, luego le estamos diciendo al compilador algo que ya sabe (que interpreta la variable datos como de tipo PChar cuando ya es de ese tipo).
El resultado final del codigo compilado se haga el cast o no es identico, simplemente el codigo fuente ocupara un pelin mas.

Saludos

Sudamericano 21-07-2006 05:17:47

Mick prueba lo que dices desarrollando una DLL que tenga compatibilidad con "C", prueba luego hablamos

coletaun 21-07-2006 10:58:06

sudamericano,es ese mi problema
 
Hola,
Ese es mi problema, trabajo con una dll externa, en c+ y el tipo de datos del pchar es el que me da problemas en delphi al pasarlo o recogerlo en una variable y pasarlo a un string.

¿como podria solucionarlo?

Ñuño Martínez 21-07-2006 11:47:51

Creo que lo tengo:

Código Delphi [-]
FUNCTION PcharToStr (aTexto: PCHAR): STRING;
BEGIN
  PcharToStr := StrPas (aTexto);
END;

Creo que esto funcionará.

Sudamericano 21-07-2006 17:51:58

coletaun mandame tu dll a mi correo y te ayudo mandandote un ejemplo en delphi con fuentes para que puedas solucionar tu problema

Mick 21-07-2006 19:39:15

STrPas es una funcion que existe solo por mantener compatibilidad hacia atras con programas antiguos y que estos no dejen de funcionar, pero borland no recomienda su uso, ya que podria ser eliminada en el futuro. La propia ayuda de delphi sobre la funcion StrPas dice:

"This function is provided for backwards compatiblity only. To convert a null terminated string to an AnsiString or native Delphi languag string, use a typecast or a assignment"

Que viene a decir:

Esta funcion existe solo por compatibilidad con programas antiguos. Para convertir una cadena terminada en nulo a un AnsiString o a un string nativo de delphi, use un typecast o una asignacion.

Saludos

PD: No importa que la funcion que devuelve el puntero a char este en una DDL igualmente no hace falta usar el typecast. Solo haria falta si lo que devuelve la funcion no fuese exactamente de tipo PChar sino de otro tipo compatible.

coletaun 24-07-2006 17:44:54

sudamericano
 
Te mando la dll y la configuración de la dll para ver si es posible que me puedas echar una mano.

Muchas gracias.

coletaun 24-07-2006 18:31:44

Mick
 
De todas formas lo que devuelve la función en c, está definido asi:
BOOL WINAPI captura_pantalla(HCLIENT hclient, char *pantalla, int *longitud, int tout);

¿que tipo de variable seria para capturar en delphi pantalla?

Gracias

Mick 25-07-2006 17:46:09

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


La franja horaria es GMT +2. Ahora son las 16:57:16.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi