Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-10-2007
mauqu mauqu is offline
Miembro
 
Registrado: may 2007
Posts: 28
Poder: 0
mauqu Va por buen camino
pasar un tipo de datos (array of record) entre aplicaciones

Estimados:

Desarrollo 2 aplicaciones donde la aplicación 1 debe enviarle sierta información a la aplicación 2 a travez de la memoria. Esta información es un array de una estructura de datos (array of record).

Para ello utilizé el siguiente código:

Aplicación 1 (aplicación que envia datos)

Código Delphi [-]
 
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellApi;
type
  TTest = packed record
    Fecha,
    Hora:TDateTime;
    Monto,
    CantCuotas:real;
    MarcaOS:string[1];
    NroTicket:int64;
    CodBarras:int64;
    CodTroquel:integer;
    Alfabeta:integer;
    CantSolicitada:integer;
    TipoBonificacion:string[2];
    ValorBonificacion:real;
  end;
  
  TForm1 = class(TForm)
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Test:array of TTest;
  //Estructura de datos para la info de la transacción
  CopyDataStruct:TCopyDataStruct;
  PAplicacion2:Thandle; //El manejador del soft 2
  Resultado:integer; 
  regs:integer;
begin
  regs:=2;
  SetLength(Test,regs);
  //Cargar los datos de la transacción
  with test[0] do
  begin
    Fecha:=now;
    Hora:=now;
    Monto:=110.20;
    CantCuotas:=1.0;
    MarcaOS:='1';
    NroTicket:=999888999;
    CodBarras:=7796930007303;
    CodTroquel:=4108371;
    Alfabeta:=0;
    CantSolicitada:=2;
    TipoBonificacion:='';
    ValorBonificacion:=0;
  end;  

  with test[1] do
  begin
    Fecha:=now;
    Hora:=now;
    Monto:=110.20;
    CantCuotas:=1.0;
    MarcaOS:='1';
    NroTicket:=999888999;
    CodBarras:=7792069002868;
    CodTroquel:=3104331;
    Alfabeta:=0;
    CantSolicitada:=1;
    TipoBonificacion:='';
    ValorBonificacion:=0;
  end;  
  //Copiar los datos de la transacción
  CopyDataStruct.dwData := 2; //Estructura
  CopyDataStruct.cbData := SizeOf(Test)*regs;
  CopyDataStruct.lpData := @Test;
 
  //Buscar el soft 2
  PAplicacion2:=findwindow('TAplication2',nil);
  if PAplicacion2 = 0 then begin //Si no lo encuentra
    //Ejecutar el soft 2
    ShellExecute(handle,
                 'open',
                 'C:\Aplicacion2.exe',
                 nil,
                 'C:\',
                 SW_SHOWNORMAL);
    sleep(1000);    
    //Buscar el soft 2
    PAplicacion2:=findwindow('TAplication2',nil);
    if PAplicacion2=0 then begin //Si no lo cuentra
      showmessage('La aplicación 2 no se puede levantada.');
      exit;
    end;
  end;
  //Enviar el mensaje WM_COPYDATA al soft 2 pasandole los datos de la transacción
  //  el mensaje de vuelta.
  Resultado:=SendMessage(PVirtualPOS,WM_COPYDATA,Integer(Handle),integer(@CopyDataStruct));
  //Mostramos el resultado.
  caption:=inttostr(resultado);
end;

Aplicación 2 (receptora)

Código Delphi [-]
 
unit fMain;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellApi;
 
type
  TTDatos = packed record
    Fecha,
    Hora:TDateTime;
    Monto,
    CantCuotas:real;
    MarcaOS:string[1];
    NroTicket:int64;
    CodBarras:int64;
    CodTroquel:integer;
    Alfabeta:integer;
    CantSolicitada:integer;
    TipoBonificacion:string[2];
    ValorBonificacion:real;
  end;
  
  TDatos = array of TTDatos;

  TfrmMain = class(TForm)
  
  private
    { Private declarations }
  public
    { Public declarations }
    procedure CopiarData(var Msg: TWMCopyData); message WM_COPYDATA;
  
  end;
var
  frmMain: TfrmMain;
implementation
{$R *.dfm}
 
procedure TfrmMain.CopiarData(var Msg: TWMCopyData);
var
  PDatos:^TDatos;
  MisDatos:TDatos;
begin
  PDatos:=Msg.CopyDataStruct.lpData;
  MisDatos:=PDatos^; // ERROR
  Msg.Result:=9999;
end;
 
end.

Cuando la aplicación 2 recibe el mensaje y trata de acceder al array me da un error de access violations.

Que es lo que no estoy contemplando ???, o, como se debe hacer esto

Saludos cordiales.

Mau
Responder Con Cita
  #2  
Antiguo 25-10-2007
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 21
Mick Va por buen camino
Una aplicacion no puede acceder a la memoria de otra aplicacion, es una medida de seguridad basica en cualquier sistema operativo decente.
Tienes que crear una zona de memoria compartida a la que se le permita acceder a otros programas, algunos ejemplos en:

http://www.delphifaq.com/faq/delphi_...API/f348.shtml
http://www.codeproject.com/threads/sharedmemipc.asp

Saludos

Última edición por Mick fecha: 25-10-2007 a las 18:03:29.
Responder Con Cita
  #3  
Antiguo 25-10-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
A ver si con este tema se soluciona algo....
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita
  #4  
Antiguo 26-10-2007
mauqu mauqu is offline
Miembro
 
Registrado: may 2007
Posts: 28
Poder: 0
mauqu Va por buen camino
Ardilla gracias por la ayuda, me sivrio mucho, pero ahora tengo un tema más :S

Probe ya usando el FileMapping y el tema es que necesito compartir un array de estructuras, y programé algo así:


Código Delphi [-]

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ShellApi;
type
TTest = packed record
Nombre,
Apellido:string[30];
end;
ATEST=array of TTest;

TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
PTest:^ATEST;
FicheroM: THandle;
begin

//Para el caso de un array, debo pasar como longitud la suma de todos sus miembros ??
FicheroM:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TTest),'Datos');
PTest:=MapViewOfFile(FicheroM,FILE_MAP_WRITE,0,0,0);

with Ptest^[0] do //Esto genera un error
begin
Nombre:='Pepe';
Apellido:='Alonso';
end;

with Ptest^[1] do
begin
Nombre:='Ludovico';
Apellido:='Pio';
end;

UnmapViewOfFile(PTest);

CloseHandle(FicheroM);

end;
end.






Entonces mi pregunta acá es, como se debe pasar un array de estructuras por medio de FileMapping ???.

Espero se entienda, gracias por la ayuda.

Mau
Responder Con Cita
  #5  
Antiguo 26-10-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
Código Delphi [-]
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellApi;
type
  TTest = packed record
    Nombre,
    Apellido:string[30];
  end;
  ATEST=array of TTest;
 
  TForm1 = class(TForm)
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
  PTest:^ATEST;
  FicheroM: THandle;
begin
 
   //Para el caso de un array, debo pasar como longitud la suma de todos sus miembros ??
   FicheroM:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TTest),'Datos');
  PTest:=MapViewOfFile(FicheroM,FILE_MAP_WRITE,0,0,0);
 
  with Ptest^[0] do //Esto genera un error
  begin
    Nombre:='Pepe';
    Apellido:='Alonso';
  end;
 
  with Ptest^[1] do
  begin
    Nombre:='Ludovico';
    Apellido:='Pio';
  end;
 
  UnmapViewOfFile(PTest);  
 
  CloseHandle(FicheroM);
 
end;
end.

Bueno, creo que la clave está es que estás intentando pasar un array de registros, pero no has reservado memoria para cada dicho array.
si verificas esto:
Código Delphi [-]
SizeOf(TTest)
antes de mapear, verás el problema.

Si leíste aquel hilo tal como te dije, también citaba esa posibilidad, reservando memoria mediante VirtualAllocEx

Recuerda que no puedes asignar elementos a un array vacio....

Luego examinando tu código, primeramente diría que la declaración del registro es incorrecta, dado que debes crear un puntero al registro.... en este caso PDatitos..

Código Delphi [-]
PDatitos = ^TDatitos;
TDatidos = packed record
    Dato_1    : Cardinal;   
    Dato_2    : Cardinal;   
    Dato_Main    : Cardinal; 
    Virtual_Mem_Adr  : Pointer;  // Dirección de memoria donde se aloja algo 
    Virtual_Men_Size : LongWord; // Longitud de memoria donde se aloja ese algo
    Etc_1 : Boolean;
end;


y luego crear o defirnir el array de una longitud fija....

Código Delphi [-]
Test_Array : Array [0..10] of TDatitos;


o dinámica

Código Delphi [-]
Test_Array: Array  of TDatitos;

En este caso debería ir asignando memória para cada elemento.

Luego podría hacer hago tal que esto para asignar valores al array


Código Delphi [-]
Test_Array[0].Dato_1 := 15;

Suerte.
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Pasar datos entre forms Phacko Varios 8 20-09-2007 23:58:08
Pasar datos entre formularios davitcito OOP 1 29-06-2005 09:48:03
Pasar parametros entre aplicaciones Iceman OOP 2 14-06-2005 16:29:25
Como Asignar Variable Tipo Array de Tform a otro Array del Mismo tipo morfeo21 Varios 5 17-08-2004 17:39:51
Pasar mensajes entre aplicaciones snuffer Varios 4 21-11-2003 01:44:21


La franja horaria es GMT +2. Ahora son las 09:18:37.


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