Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Delphi para la web (https://www.clubdelphi.com/foros/forumdisplay.php?f=51)
-   -   Componente indy dentro de una dll (https://www.clubdelphi.com/foros/showthread.php?t=95013)

Punzo 07-01-2021 00:34:10

Componente indy dentro de una dll
 
Buen día a todos, hay algunos factores a tomar en cuenta para hacer una dll con indy 10.6.2 y su componente TidTCPClient?, ya que quiero convertir un exe, que funciona sin problemas, y al pasarlo a dll, me genera Access Violations, en 2 partes que con el exe no lo hace; lo más raro de todo, es que lo hace bien la primera vez, dejo la parte del código(comento las parte donde me da el error), dónde tengo el problema, gracias de antemano.
Código Delphi [-]
procedure TfmConfiguracion.btCargaFamiliasClick(Sender: TObject);
var
  R, Codigo :String;
  JF :TJSONObject;
  Familia :TFamilia;
  NumB, i :Integer;
begin
if (edCaja.Text <> '') and (edTurno.Text <> '') then
  begin
    if NumFam = 0 then
      begin
        SetLength(AFam, NumFam + 1);
        AFam[NumFam] := '000000';
        Codigo := AFam[NumFam];
      end
      else if (Sender is TFamilia) then
        begin
          SetLength(AFam, NumFam + 1);
          AFam[NumFam] := (Sender as TFamilia).Codigo;
          Codigo := AFam[NumFam];
        end
        else
          begin
            Codigo := AFam[NumFam];
          end;
    //  Aquí me manda un Access Violation, la tercera vez que le doy click al boton que dice "cerveza", 
    //  pero no me da el error si le doy click al boton que dice "brandy"
    ClienConLocal.SendCmd('carga_familia ' + Codigo + ' ' + edCaja.Text + ' ' + edTurno.Text + ' ' + IDCliente);
    R := ClienConLocal.LastCmdResult.Text.Text;
    JF := TJSONObject.Parse(R) as TJSONObject;
    NumB := JF['botones'].Count;
    if (NumB > 0) or (JF.S['ayb_fam'] = 'F') then
      begin
        LimpiarPanel(pnFamilias);
        Inc(NumFam);
      end
      else
        begin
          if MessageDlg('¿Estás seguro de agregar ' + (Sender as Tfamilia).Descripcion + ' a Terminados?',
                        mtConfirmation, [mbYes, mbNo], 0, mbYes) = mrYes then
            begin
              LlenarGrid(Sender);
            end;
        end;

    for i := 1 to NumB do
      begin
        Familia := TFamilia.Create(pnFamilias);//Despúes de 3 veces de darle click, me manda el Acces Violation
        Familia.Descripcion := TBase64Encoding.Base64.Decode(JF['botones'].ArrayValue.O[i - 1].S['descrip']);
        Familia.Caption := TBase64Encoding.Base64.Decode(JF['botones'].ArrayValue.O[i - 1].S['descrip']);
        Familia.Codigo := JF['botones'].ArrayValue.O[i - 1].S['codigo'];
        Familia.Precio :=  JF['botones'].ArrayValue.O[i - 1].S['precio'];
        Familia.Impto1 := JF['botones'].ArrayValue.O[i - 1].S['impto1'];
        Familia.Impto2 := JF['botones'].ArrayValue.O[i - 1].S['impto2'];
        Familia.Imprime := JF['botones'].ArrayValue.O[i - 1].S['imprime'];
        Familia.Servicio := JF['botones'].ArrayValue.O[i - 1].S['servicio'];
        Familia.AyB_Fam := JF['botones'].ArrayValue.O[i - 1].S['tipo_ayb'];
        if JF['botones'].ArrayValue.O[i - 1].S['terminado'] = 'S' then
          Familia.Terminado := True
        else
          Familia.Terminado := False;
        Familia.Enabled := Familia.Terminado;
        if JF['botones'].ArrayValue.O[i - 1].S['indica'] <> '' then
          Familia.Indicaciones := JF['botones'].ArrayValue.O[i - 1].S['indica'];
        if JF['botones'].ArrayValue.O[i - 1].S['sugerencias'] <> '' then
          Familia.Sugerencias := JF['botones'].ArrayValue.O[i - 1].S['sugerencias'];
        Familia.Parent := pnFamilias;
        Familia.Font.Size := 10;
        Familia.WordWrap := True;
        Familia.Width := 90;
        Familia.Height := 90;
        Familia.Margins.Left := 5;
        Familia.Margins.Top := 5;
        Familia.Margins.Right := 5;
        Familia.Margins.Bottom := 5;
        Familia.OnClick := btCargaFamiliasClick;
      end;
  end
  else
    ShowMessage('Los campos Caja y Turno son obligatorios');
end;

Neftali [Germán.Estévez] 07-01-2021 12:58:37

Lo más sencillo es que crees un pequeño proyecto (o dos uno para el EXE y otro para la DLL) donde se reproduzca el error y con el mínimo código posible y lo subas (como ZIP).
De esa forma podemos probarlo y darte la solución, de otra forma es difícil saber qué puede estar pasando...


Cita:

Empezado por Punzo (Mensaje 539622)
lo más raro de todo, es que lo hace bien la primera vez

Eso puede ser indicativo de que algo en la DLL no se está cargando/descargando correctamente. Y al hacerlo la segunda vez falla.
Enl código de la DLL sería útil para saber qué está pasando.

Punzo 07-01-2021 21:49:22

Muchas gracias por la ayuda, de hecho este código es el que tengo en el proyecto en .exe, y funciona sin problemas, de ahí mi duda de que tengo, que tomar en cuenta para hacer este tipo de conversión de .exe a .dll con el componente TidTCPClient, la .dll la estoy haciendo dinámica, entonces puede ser que no este cargando bien la .dll?

Punzo 07-01-2021 22:01:37

Este es el código de mi .dll
Código Delphi [-]
library ConfiguraciónPDVDLL;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  System.SysUtils,
  System.Classes,
  VCL.Forms,
  Windows,
  IdTCPClient,
  Dialogs,
  UConfiguracion in 'UConfiguracion.pas' {fmConfiguracion},
  UdmConexion in 'UdmConexion.pas' {dmConexion: TDataModule},
  UFamilia in '..\..\UnitsCompartidas\UFamilia.pas',
  JsonDataObjects in '..\..\UnitsCompartidas\JsonDataObjects.pas',
  uErrorDescrip in '..\..\UnitsCompartidas\uErrorDescrip.pas';

var
  DLLApp :TApplication;

{$R *.res}

procedure Crear(ParentApp :TApplication; var ClienCon :TIdTCPClient; IDClien :String); stdcall;
begin
  Application := ParentApp;
  //ShowMessage({'IDCliente param DLL: ' + IDCliente +} ' Port: ' + IntToStr(ClienCon.Port));
  fmConfiguracion := TfmConfiguracion.Create(nil);
  fmConfiguracion.Show;
  fmConfiguracion.ClienConLocal := ClienCon;
  IDCliente := IDClien;
  if Not(fmConfiguracion.ClienConLocal.Connected) then
    fmConfiguracion.ClienConLocal.Connect;
end;

procedure DLLUnload(Reason: Integer); register;
begin
  if Reason = DLL_PROCESS_DETACH then
    Application := DLLApp;
end;

exports
  Crear;

begin
  isMultiThread := True;
  DLLApp := Application;
  DLLProc := @DLLUnload;
end.

Neftali [Germán.Estévez] 08-01-2021 14:17:59

¿Has mirado el comentario que hay al principio del fichero?


La franja horaria es GMT +2. Ahora son las 00:44:58.

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