Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   ¿Como crear un ejecutable que llame un DLL? (https://www.clubdelphi.com/foros/showthread.php?t=79344)

mweltmeister 27-06-2012 10:11:44

¿Como crear un ejecutable que llame un DLL?
 
Hola, muy buenas a todos.
Antes que nada, como soy nuevo en el foro, les doy mis felicitaciones por la voluntad y la ayuda de sus colaboradores.
Espero que con el tiempo y después de un largo aprendizaje, pueda colaborar y aportar ayudando a los demás como usuarios con grandes conocimientos que hay aquí lo hacen.

Soy nuevo en esto de la programación y decidí iniciarme con Delphi, se que lo primero que me van a decir es que "utilice el buscador"; Hace más de 3 horas (literal) que estoy buscando ayuda por todo internet (más que nada acá), vi muchos temas pero ninguno solucionó mi pregunta. Prácticamente me esta volviendo loco y por eso considero necesario abrir un nuevo tema para ver si me pueden ayudar.


Tengo un código DLL (solo el código) y decidí compilarlo en Delphi XE2, hasta ahí perfecto...

Para llamar a ese DLL y que se ejecute, necesito crear un ejecutable (valga la redundancia); Según el autor debemos crear un ejecutable que exporte la función "StartHook" para llamar.

La pregunta es: ¿Cómo creo un .exe que incluya la función "StartHook"?

Ya intenté lo siguiente: Crear el .exe pulsando F9 a lo que me sale el siguiente error: "Cannot run project unless a host application...".
Exacto, pero si solo tengo el .dll cual es la aplicación host.

También intenté crear un .exe desde 0 que llame el .dll con varios tutoriales que encontré en la web, pero nada.



Muchas gracias a todos de antemano, y felicitaciones por el foro.

Neftali [Germán.Estévez] 27-06-2012 11:24:15

Hola.
En esta entrada puedes ver la explicación de cómo cargar DLL y BPLs desde Delphi.
En concreto si no quieres revisar todo, en lo que concierne a DLL's, las dos primeras secciones explican cómo cargar una DLL de forma estática y de forma dinámica.
También puedes descargar el código de todos los ejemplos.

En concreto, tienes uno para generar la DLL (sumas.dll) y dos proyectos (call_suma_estat y call_suma_dinam) para que veas cómo se carga la anterior DLL con ambos métodos.

Échale un vistazo al código de los ejemplos y verás que es sencillo.

Un saludo.

mweltmeister 27-06-2012 11:40:30

Cita:

Empezado por Neftali (Mensaje 436106)
Hola.
En esta entrada puedes ver la explicación de cómo cargar DLL y BPLs desde Delphi[/url].
En concreto si no quieres revisar todo, en lo que concierne a DLL's, las dos primeras secciones explican cómo cargar una DLL de forma estática y de forma dinámica.
También puedes descargar el código de todos los ejemplos[/url].

En concreto, tienes uno para generar la DLL (sumas.dll) y dos proyectos (call_suma_estat y call_suma_dinam) para que veas cómo se carga la anterior DLL con ambos métodos.

Échale un vistazo al código de los ejemplos y verás que es sencillo.

Un saludo.


Hola Netfali! Antes que nada quiero agradecer tu pronta respuesta. Estuve leyendo la información que me facilitaste pero no puedo ejecutar el .dll!!

Estoy trabajando bajo Delphi XE2 y no abre los archivos que están para descargar, supongo porque se hicieron en una versión más antigua de Delphi.

Ahora tengo claro que lo que quiero es crear un .exe + .dll con carga estática. ¡No puedo resolver lo del .exe!
Ya lo tengo compilado, no se ni por donde empezar a crear el .exe sinceramente y no encuentro una explicación que me funcione como hacerlo.
O soy muy torpe o el hecho de que sean las 6:45 de la mañana (acá en Argentina) y que esté desde las 11:00 de la noche intentando hacerlo me dejo atontado; Aunque, no pienso dormir hasta lograrlo.

Ahora sigo intentando, gracias por tu ayuda.

mweltmeister 27-06-2012 11:48:00

¡Pude abrir uno de los proyectos!
Estoy intentando modificar el código para que me funcione con el .dll pero me da un error al querer compilarlo.
El código que intento compilar es el siguiente; ¿Alguna idea?

Código:

program Call_suma_estat;

uses
  Forms,
  Dialogs,
  SysUtils;

var
  Res:Integer;

function StartHook(x,y:integer):Integer; stdcall; external 'project1.dll';


begin
  // llamada
  Res := StartHook;
  MessageDlg('Iniciando programa.....', mtInformation, [mbOK], 0);

end.


Casimiro Notevi 27-06-2012 11:52:21

Cita:

Empezado por mweltmeister (Mensaje 436109)
me da un error al querer compilarlo.

Deberías poner el mensaje del error ;)

mweltmeister 27-06-2012 11:56:07

Perdón, se me olvidó. No estoy seguro de cual fue el mensaje del error, pero marcaba en rojo el codigo "Res= 0".

Intenté editarlo a mi manera para que funcionara con el comando que yo quiero y pude compilarlo; El problema es que el .dll no funciona!.
Lo único que hace el .exe al ser ejecutado es mostrar una ventana que dice "Iniciando programa" (como el código muestra).

Adjunto nuevamente el código que pude compilar:
Código:

program start;

uses
  Forms,
  Dialogs,
  SysUtils;

var
  Res:Integer;

function StartHook(x,y:integer):Integer; stdcall; external 'project1.dll';


begin
  // llamada
  Res := 0;
  MessageDlg('Iniciando programa.....', mtInformation, [mbOK], 0);

end.

Ah, y más que nada gracias por la ayuda que me están brindando. Avance más en 10 minutos con su ayuda que en 4 horas de búsqueda y trabajo.
Gracias!

Neftali [Germán.Estévez] 27-06-2012 12:31:45

No debería haber problema con la versión.

(1) Abre el proyecto de sumas (dpk o dproj) y compílalo
=> Eso debería generar una DLL en el directorio.

(si te da algún error dí cual)

(2) Cierra el proyecto anterior y abre el proyecto Call_suma_estat (dpk o dproj) y compílalo
=> Eso debería generar un EXE en el directorio.

(si te da algún error dí cual)

Esperamos que nos digas que tal...

mweltmeister 27-06-2012 12:39:27

Creo que no me expliqué adecuadamente o no te entendí, pero hice lo que me dijiste y el error al compilar fue el siguiente: "[DCC Fatal Error] sumas.dpr(8): F1026 File not found: 'Dialogs.dcu'"

Código:
Código:

library sumas;


uses
  ShareMem,
  Dialogs,
  SysUtils,
  Classes;

{$R *.res}


function Sumar(x,y:integer):Integer; stdcall; overload;
begin
  ShowMessage (Format('1-Sumando %d+%d=%d',[x,y,(x+y)]));
  Result := x+y;
end;

function Sumar2(x,y:integer):Integer; stdcall; overload;
begin
  ShowMessage (Format('2-Sumando %d+%d=%d',[x,y,(x+y)]));
  Result := x+y;
end;


exports Sumar(x,y:integer);
exports Sumar2(x,y:integer);

end.

El error se marca en rojo en:
Código:

Classes;

Neftali [Germán.Estévez] 27-06-2012 13:05:35

Cita:

Empezado por mweltmeister (Mensaje 436116)
Creo que no me expliqué adecuadamente o no te entendí, pero hice lo que me dijiste y el error al compilar fue el siguiente: "[DCC Fatal Error] sumas.dpr(8): F1026 File not found: 'Dialogs.dcu'"

Perdón.
Tienes TODA la razón.

Al trabajar con Delphi XE2 hay que cambiar referencias a algunas units.
Cambia Dialogs por VCL.Dialogs y prueba.

mweltmeister 27-06-2012 13:55:53

Cita:

Empezado por Neftali (Mensaje 436117)
Perdón.
Tienes TODA la razón.

Al trabajar con Delphi XE2 hay que cambiar referencias a algunas units.
Cambia Dialogs por VCL.Dialogs y prueba.

Ya me funcionó la compilación, ya lo tengo compilado y ya puedo llamar al .dll; El problema es que no funciona!!

Supongo que es por un error donde dice "var
Use: function(x,y:Integer):integer; stdcall;"
Ya que la función no es esa, la función que quiero utilizar es "StartHook" o algo que la ejecute.

¿Alguna otra idea?
Código:

program Call_suma_dinam;

uses
  Sharemem,
  SysUtils,
  Classes,
  Windows,
  VCL.Dialogs;

{$R *.res}

var
  H: Thandle;
  res:integer;
  Use: function(x,y:Integer):integer; stdcall;
begin

  if (MessageBox(0, '¿Desea cargar la DLL?', '', MB_ICONQUESTION or MB_YESNO) = idNo) then begin
    Exit;
  end;

  H := LoadLibrary('Project1.dll');
  // Cargada correctamente?
  if (H >= 32) then begin
    MessageDlg('Cargada la DLL...', mtInformation, [mbOK], 0);
    sum := nil;
    @sum := GetProcAddress(H, 'StartHook');
    // Asignada?
    if Assigned(sum) then begin
      MessageDlg('Acceso a la función StartHook', mtInformation, [mbOK], 0);
      // llamada
      res := Sum(Starthook);

      MessageDlg(Format('Resultado:  %d+%d=%d',[4,5,res]), mtInformation, [mbOK], 0);
      FreeLibrary(H);
    end;
  end
  else
    MessageDlg('Error, no se ha encontrado SUMAR.DLL', mtError, [mbOk], 0)
 end.
end.


escafandra 27-06-2012 15:13:43

¿Estas utilizando un Win32 o un Win64?.

Suponiendo que importas bien la función StartHook y que su declaración es correcta, si ese Hook que realiza la dll que quieres usar requiere su inyección en procesos de 64 bits, dicha inyección no se va a realizar. Un proceso compilado para 64 bits no puede cargar una dll compilada para 32 bits. :)


Saludos.

Neftali [Germán.Estévez] 27-06-2012 15:35:27

¿Exactamente qué cabecera tienen esas funciones?
¿Cómo están definidas?

Neftali [Germán.Estévez] 27-06-2012 15:41:39

Prueba con algo así y te debería funcionar:;

Código Delphi [-]
var
  H: Thandle;
  res:integer;
  proc: procedure();stdcall;
begin
  H := LoadLibrary('Project1.dll');
  // Cargada correctamente?
  if (H >= 32) then begin
    MessageDlg('Cargada la DLL...', mtInformation, [mbOK], 0);
    proc := nil;
    @proc := GetProcAddress(H, 'StartHook');
    // Asignada?
    if Assigned(proc) then begin
      MessageDlg('Acceso a la función StartHook', mtInformation, [mbOK], 0);
      // llamada
      proc();
      MessageDlg('Se ha ejecutadoStartHook', mtInformation, [mbOK], 0);
      // Liberar
      FreeLibrary(H);
    end;
  end
  else
    MessageDlg('Error, no se ha encontrado Project1.DLL', mtError, [mbOk], 0)
 end.
end.

Para comprobarlo pon un dialog dentro del procedimiento y verás si se ejecuta.
Aquí he supuesto que la cabecera de la función coincide con esta:

Código Delphi [-]
proc: procedure();stdcall;

mweltmeister 27-06-2012 17:25:38

Ahí compiló perfectamente, pero ahora el .exe por más que me diga que llama al .dll aparentemente no lo hace!.
Eliminé el .dll de todos lados y aún así dice haberlo encontrado y acceder a su función.

Y si los ejecuto juntos, aparentemente también dice acceder a su función aunque no haga nada de lo que debería hacer (el .dll)

¿Alguna idea? Me estoy volviendo loco con esto...
Gracias!

Neftali [Germán.Estévez] 28-06-2012 09:36:23

Cita:

Empezado por mweltmeister (Mensaje 436135)
Ahí compiló perfectamente, pero ahora el .exe por más que me diga que llama al .dll aparentemente no lo hace!.
Eliminé el .dll de todos lados y aún así dice haberlo encontrado y acceder a su función.

Y si los ejecuto juntos, aparentemente también dice acceder a su función aunque no haga nada de lo que debería hacer (el .dll)
¿Alguna idea? Me estoy volviendo loco con esto...

Entiende que es difícil saber qué está pasando sin ver el código de la DLL.
Añade un cuadro me mensaje a la DLL cuando se ejecute, así podrás ver si está pasando por ese punto y si la está ejecutando.

¿Qué debería hacer esa DLL?


La franja horaria es GMT +2. Ahora son las 07:27:19.

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