PDA

Ver la Versión Completa : Componente indy dentro de una dll


Punzo
06-01-2021, 23:34:10
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.

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, 11: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...


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, 20: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, 21:01:37
Este es el código de mi .dll

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, 13:17:59
¿Has mirado el comentario que hay al principio del fichero?