PDA

Ver la Versión Completa : pasar contenido de pchar a string


coletaun
21-07-2006, 01:46:42
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.


for I:=1 to Max do
begin
cString[i]:=cChar[i];
end;


Suerte.

coletaun
21-07-2006, 02:38:01
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.


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


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
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:

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
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
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:


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:


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:


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:


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.


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