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 13-01-2014
elmago00 elmago00 is offline
Miembro
NULL
 
Registrado: ago 2013
Posts: 86
Poder: 11
elmago00 Va por buen camino
problema con embarcadero y dll

hola,
hace días estoy desarrollando una aplicación que llame a una dll, esta dll obtiene un string, por lo que le paso como parámetro un texbox, luego la dll devuelve un array. todo al parecer funciona no tengo ningún error, ningún warning.
pero embarcadero xe3 se cierra automáticamente, no inicia la aplicación, solo empieza a compilar y no lo finaliza. e creado 10 programas grandes en delphi, pero en ninguno e implementado una dll.

así que intente, hacer pruebas con los ejemplos que hay aquí, 5 para ser específicos, luego intente con lo que esta en delphibasic y obtengo lo mismo, solo empieza a compilar y después no hace nada. repito que no me da ningún error ni llamada de atención.

algún experto en dll, que me pueda dar un pequeñísimo ejemplo de dll, sin que se me cierre el compilador.

muchas gracias
Responder Con Cita
  #2  
Antiguo 14-01-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola elmago00.

Sin ver tu código es difícil sino imposible poder saber que sucede y por tanto darte un ejemplo específico. Pero te pongo unos enlaces que pueden ayudarte con el manejo de DLL's en Delphi:.
Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 14-01-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
elmago00,

Cita:
Empezado por elmago00
...algún experto en dll, que me pueda dar un pequeñísimo ejemplo de dll...
No soy un experto en Delphi, pero tratare de ayudar lo mejor que pueda

Revisa este código:
Código Delphi [-]
 unit Unit1;
 
 interface
 
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls;
 
 type
   TForm1 = class(TForm)
     Edit1: TEdit;
     Memo1: TMemo;
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end;
 
   TA1 = Array of String;
   TA2 = Array of Integer;
   TA3 = Array of Double;
 
   function FA1(Value : String) : TA1; stdcall; external 'TestDLL.dll';
   function FA2(Value : String) : TA2; stdcall; external 'TestDLL.dll';
   function FA3(Value : String) : TA3; stdcall; external 'TestDLL.dll';
 
 var
   Form1: TForm1;
 
 implementation
 
 {$R *.dfm}
 
 function StringToCaseSelect(Selector : string; CaseList: array of string): Integer;
 var
    pos: integer;
 begin
    Result := -1;
    for pos := 0 to Length(CaseList)-1 do
    begin
       if CompareText(Selector, CaseList[pos]) = 0 then
       begin
          Result :=  pos;
          Break;
       end;
    end;
 end;
 
 procedure TForm1.Button1Click(Sender: TObject);
 var
    A1 : TA1;
    A2 : TA2;
    A3 : TA3;
    i : Integer;
 
 begin
 
    case StringToCaseSelect(Edit1.Text,['A1','A2','A3']) of
       0 : A1 := FA1(Edit1.Text);
       1 : A2 := FA2(Edit1.Text);
       2 : A3 := FA3(Edit1.Text);
    else
       MessageDlg('Solo se permiten los valores string A1, A2 y A3', mtInformation, [mbOK], 0);
    end;
 
    Memo1.Clear;
 
    if Length(A1) > 0 then
       for i := Low(A1) to High(A1) do
          Memo1.Lines.Add(A1[i]);
 
    if Length(A2) > 0 then
       for i := Low(A2) to High(A2) do
          Memo1.Lines.Add(IntToStr(A2[i]));
 
    if Length(A3) > 0 then
       for i := Low(A3) to High(A3) do
          Memo1.Lines.Add(FloatToStr(A3[i]));
 
 end;
 
 end.
El código anterior en Delphi 2010 bajo Windows 7 Professional x32, implementa tres funciones exportadas por un DLL en un programa tipo Desktop bajo Windows.

Revisa este código:
Código Delphi [-]
 library TestDLL;
 
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, StdCtrls;

 type
   TA1 = Array of String;
   TA2 = Array of Integer;
   TA3 = Array of Double;
 
 
 {$R *.res}
 
 function FA1(Value : String) : TA1; stdcall;
 var
    A1 : TA1;
    i : Integer;
 
 begin
 
    if Value = 'A1' then
    begin
 
       SetLength(A1,10);
 
       Randomize;
 
       for i := 0 to 9 do
          A1[i] := 'Number-' + IntToStr(Random(100));
 
       Result := A1;
 
    end
    else
    begin
       SetLength(A1,1);
       A1[0] := 'La función esperaba A1 como string y recibio : ' + Value;
       Result := A1;
    end;
 
 
 end;
 
 function FA2(Value : String) : TA2; stdcall;
 var
    A2 : TA2;
    i : Integer;
 
 begin
 
    if Value = 'A2' then
    begin
 
       SetLength(A2,10);
 
       Randomize;
       for i := 0 to 9 do
          A2[i] := Random(100);
 
       Result := A2;
 
    end
    else
    begin
       SetLength(A2,1);
       A2[0] := High(Integer);
       Result := A2;
    end;
 
 end;
 
 function FA3(Value : String) : TA3; stdcall;
 var
    A3 : TA3;
    i : Integer;
 
 begin
 
    if Value = 'A3' then
    begin
 
       SetLength(A3,10);
 
       Randomize;
       for i := 0 to 9 do
          A3[i] := Random;
 
       Result := A3;
 
    end
    else
    begin
       SetLength(A3,1);
       A3[0] := 3.1415927;
       Result := A3;
    end;
 
 end;
 
 exports
    FA1, FA2, FA3;
 
 begin
 end.
El código anterior en Delphi 2010 bajo Windows 7 Professional x32, implementa un DLL que exporta tres funciones en la cual cada una devolverá un array en función del string de entrada, en caso de que el string recibido no sea el correcto se devuelve un valor por defecto.

Nota: Los códigos anteriores funcionan correctamente en una Máquina Física con Delphi 2010 bajo Windows 7 Professional x32 y en una Máquina Virtual con Delphi XE4 bajo Windows 7 Professional x32, si el evento que describes se repite nuevamente con el ejemplo propuesto, te sugiero revisar la instalación de Delphi XE3 y en caso contrario la aplicación y dll en cuestión..

Espero sea útil

Nelson.

Última edición por Casimiro Notevi fecha: 15-01-2014 a las 19:54:01.
Responder Con Cita
  #4  
Antiguo 16-01-2014
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
elmago00,

Revisa esta información:
Cita:
In general, functions in a DLL can use any type of parameter and return any type of value. There are two exceptions to this rule:
  • If you plan to call the DLL from other programming languages, you should try using Windows native data types instead of Delphi-specific types. For example, to express color values, you should use integers or the Windows ColorRef type instead of the Delphi native TColor type, doing the appropriate conversions (as in the FormDLL example, described in the next section). For compatibility, you should avoid using some other Delphi types, including objects (which cannot be used by other languages) and Delphi strings (which can be replaced by PChar strings). In other words, every Windows development environment must support the basic types of the API, and if you stick to them, your DLL will be usable with other development environments. Also, Delphi file variables (text files and binary file of record) should not be passed out of DLLs, but you can use Win32 file handles.
  • Even if you plan to use the DLL only from a Delphi application, you cannot pass Delphi strings (and dynamic arrays) across the DLL boundary without taking some precautions. This is the case because of the way Delphi manages strings in memory—allocating, reallocating, and freeing them automatically. The solution to the problem is to include the ShareMem system unit both in the DLL and in the program using it. This unit must be included as the first unit of each of the projects. Moreover, you have to deploy the BorlndMM.DLL file (the name stands for Borland Memory Manager) along with the program and the specific library.
Tomado del link : http://etutorials.org/Programming/ma...DLL+in+Delphi/
En el ejemplo del DLL propuesto en el Msg #3, No se siguieron las reglas descritas anteriormente dado que funciono correctamente en Delphi 2010 y Delphi XE4 (Asumo que también funcionaría en Delphi XE3), sin embargo en Delphi 7 los ejemplos descritos no funcionan correctamente, dado que en esta versión las reglas mencionadas son válidas.

En lo personal independientemente de la versión de Delphi que se utilice siempre es preferible seguir las reglas anteriores por compatibilidad con otros lenguajes en Windows, pero si el DLL y el programa son ambos programados en Delphi 2010 o Delphi XE4 (Solo menciono estas versiones por que son las que he probado en el ejemplo, pero lo más probable es que se cumpla de Delphi 2010 a Delphi XE5), es posible hacer el desarrollo del DLL y su programa asociado como se sugiere en el mensaje anterior en lo relacionado al uso de arreglos y strings como parámetros de un DLL.

Para evitar usar como parámetros Arreglos y Strings en Delphi DLLs, estos pueden ser sustituidos por medio de tipos PChar que permitan un medio confiable de intercambio de información entre diferentes lenguajes bajo Windows.

Revisa este código:
Código Delphi [-]
library TestDLL2;

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

{$R *.res}

function GetArraySim(Value : PChar) : PChar; stdcall;
var
   i : Integer;
   AuxStr : String;
   StrList : TStringList;

begin

   StrList := TStringList.Create;

   if (Value = 'Integer') then
   begin

      Randomize;

      for i := 0 to 9 do
      begin
         AuxStr := IntToStr(Random(1000));
         StrList.Add(AuxStr);
      end;

      Result := PChar(StrList.CommaText);

   end;

   if (Value = 'Double') then
   begin

      Randomize;

      for i := 0 to 9 do
      begin
         AuxStr := FormatFloat('##0.00',(Random(100)+Random));
         StrList.Add(AuxStr);
      end;

      Result :=PChar(StrList.CommaText);

   end;

   if (Value = 'String') then
   begin

      Randomize;

      for i := 0 to 9 do
      begin
         AuxStr := 'String-' + IntToStr(Random(1000));
         StrList.Add(AuxStr);
      end;

      Result :=PChar(StrList.CommaText);

   end;

   if (Value <> 'Integer') and (Value <> 'Double') and (Value <> 'String') then  
   begin
      MessageDlg('Error en String de Selección',mtInformation,[mbOK],0);
      Result := PChar(EmptyStr);
   end;

   StrList.Free;

end;

exports
   GetArraySim;

begin
end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32, implementa un DLL que recibe un Pchar de entrada y devuelve un Pchar de salida que contiene varios items de tipo Integer, Double y String delimitados por coma, la idea es simular un arreglo de salida por medio de datos de tipo TStrinList y Pchar.

Revisa este código
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  function SimulaArray(Value : PChar) : PChar; stdcall; external 'TestDLL2.dll' name 'GetArraySim';

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
   ComboBox1.Items.Add('Integer');
   ComboBox1.Items.Add('Double');
   ComboBox1.Items.Add('String');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   ArrInt : Array of Integer;
   ArrDbl : Array of Double;
   ArrStr : Array of String;
   i : Integer;
   Msg : String;
   StrList : TStringList;

begin

   Memo1.Clear;

   StrList := TStringList.Create;

   if ComboBox1.Text = 'Integer' then
   begin
      StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
      SetLength(ArrInt,StrList.Count);
      for i := 0 to StrList.Count-1 do
      begin
         ArrInt[i] := StrToInt(StrList.Strings[i]);
         Memo1.Lines.Add(IntToStr(ArrInt[i]));
      end;
   end;

   if ComboBox1.Text = 'Double' then
   begin
      StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
      SetLength(ArrDbl,StrList.Count);
      for i := 0 to StrList.Count-1 do
      begin
         ArrDbl[i] := StrToFloat(StrList.Strings[i]);
         Memo1.Lines.Add(FloatToStr(ArrDbl[i]));
      end;
   end;

   if ComboBox1.Text = 'String' then
   begin
      StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
      SetLength(ArrStr,StrList.Count);
      for i := 0 to StrList.Count-1 do
      begin
         ArrStr[i] := StrList.Strings[i];
         Memo1.Lines.Add(ArrStr[i]);
      end;
   end;

   StrList.Free;

end;

end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32, implementa el DLL (TestDLL2) que simula el arreglo de salida indicado anteriormente.

De esta forma se pueden pasar gran cantidad de datos hacia y desde el DLL por medio de datos de tipo TStrinList y Pchar, otra forma es por medio de Estructuras Tipo Record por Referencia, pero solo en los casos que amerite este tipo de datos.

Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 16-01-2014 a las 03:49:40.
Responder Con Cita
  #5  
Antiguo 16-01-2014
elmago00 elmago00 is offline
Miembro
NULL
 
Registrado: ago 2013
Posts: 86
Poder: 11
elmago00 Va por buen camino
Talking

Cita:
Empezado por nlsgarcia Ver Mensaje
elmago00,

Revisa esta información:

En el ejemplo del DLL propuesto en el Msg #3, No se siguieron las reglas descritas anteriormente dado que funciono correctamente en Delphi 2010 y Delphi XE4 (Asumo que también funcionaría en Delphi XE3), sin embargo en Delphi 7 los ejemplos descritos no funcionan correctamente, dado que en esta versión las reglas mencionadas son válidas.

En lo personal independientemente de la versión de Delphi que se utilice siempre es preferible seguir las reglas anteriores por compatibilidad con otros lenguajes en Windows, pero si el DLL y el programa son ambos programados en Delphi 2010 o Delphi XE4 (Solo menciono estas versiones por que son las que he probado en el ejemplo, pero lo más probable es que se cumpla de Delphi 2010 a Delphi XE5), es posible hacer el desarrollo del DLL y su programa asociado como se sugiere en el mensaje anterior en lo relacionado al uso de arreglos y strings como parámetros de un DLL.

Para evitar usar como parámetros Arreglos y Strings en Delphi DLLs, estos pueden ser sustituidos por medio de tipos PChar que permitan un medio confiable de intercambio de información entre diferentes lenguajes bajo Windows.

Revisa este código:
Código Delphi [-]
library TestDLL2;

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

{$R *.res}

function GetArraySim(Value : PChar) : PChar; stdcall;
var
   i : Integer;
   AuxStr : String;
   StrList : TStringList;

begin

   StrList := TStringList.Create;

   if (Value = 'Integer') then
   begin

      Randomize;

      for i := 0 to 9 do
      begin
         AuxStr := IntToStr(Random(1000));
         StrList.Add(AuxStr);
      end;

      Result := PChar(StrList.CommaText);

   end;

   if (Value = 'Double') then
   begin

      Randomize;

      for i := 0 to 9 do
      begin
         AuxStr := FormatFloat('##0.00',(Random(100)+Random));
         StrList.Add(AuxStr);
      end;

      Result :=PChar(StrList.CommaText);

   end;

   if (Value = 'String') then
   begin

      Randomize;

      for i := 0 to 9 do
      begin
         AuxStr := 'String-' + IntToStr(Random(1000));
         StrList.Add(AuxStr);
      end;

      Result :=PChar(StrList.CommaText);

   end;

   if (Value <> 'Integer') and (Value <> 'Double') and (Value <> 'String') then  
   begin
      MessageDlg('Error en String de Selección',mtInformation,[mbOK],0);
      Result := PChar(EmptyStr);
   end;

   StrList.Free;

end;

exports
   GetArraySim;

begin
end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32, implementa un DLL que recibe un Pchar de entrada y devuelve un Pchar de salida que contiene varios items de tipo Integer, Double y String delimitados por coma, la idea es simular un arreglo de salida por medio de datos de tipo TStrinList y Pchar.

Revisa este código
Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    ComboBox1: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  function SimulaArray(Value : PChar) : PChar; stdcall; external 'TestDLL2.dll' name 'GetArraySim';

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
   ComboBox1.Items.Add('Integer');
   ComboBox1.Items.Add('Double');
   ComboBox1.Items.Add('String');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   ArrInt : Array of Integer;
   ArrDbl : Array of Double;
   ArrStr : Array of String;
   i : Integer;
   Msg : String;
   StrList : TStringList;

begin

   Memo1.Clear;

   StrList := TStringList.Create;

   if ComboBox1.Text = 'Integer' then
   begin
      StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
      SetLength(ArrInt,StrList.Count);
      for i := 0 to StrList.Count-1 do
      begin
         ArrInt[i] := StrToInt(StrList.Strings[i]);
         Memo1.Lines.Add(IntToStr(ArrInt[i]));
      end;
   end;

   if ComboBox1.Text = 'Double' then
   begin
      StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
      SetLength(ArrDbl,StrList.Count);
      for i := 0 to StrList.Count-1 do
      begin
         ArrDbl[i] := StrToFloat(StrList.Strings[i]);
         Memo1.Lines.Add(FloatToStr(ArrDbl[i]));
      end;
   end;

   if ComboBox1.Text = 'String' then
   begin
      StrList.CommaText := SimulaArray(PChar(ComboBox1.Text));
      SetLength(ArrStr,StrList.Count);
      for i := 0 to StrList.Count-1 do
      begin
         ArrStr[i] := StrList.Strings[i];
         Memo1.Lines.Add(ArrStr[i]);
      end;
   end;

   StrList.Free;

end;

end.
El código anterior en Delphi 7 bajo Windows 7 Professional x32, implementa el DLL (TestDLL2) que simula el arreglo de salida indicado anteriormente.

De esta forma se pueden pasar gran cantidad de datos hacia y desde el DLL por medio de datos de tipo TStrinList y Pchar, otra forma es por medio de Estructuras Tipo Record por Referencia, pero solo en los casos que amerite este tipo de datos.

Espero sea útil

Nelson.


Hermano, eres un genio! llegaste justo al problema, y todo salio al 100%, mil gracias a todos por responder.
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
Embarcadero adquiere AnyDAC jxsoftware Noticias 23 13-11-2020 10:00:16
Puestos de trabajo en embarcadero? droguerman Noticias 22 09-08-2010 20:58:34
Codegear & Embarcadero Emilio Noticias 19 10-06-2008 22:58:47


La franja horaria es GMT +2. Ahora son las 20:54:20.


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