Fórum Como chamar uma dll pelo WinExec, CreateProcess??? #350231
07/12/2007
0
Eu tenho uma dll e preciso chamá-la no Delphi, porém eu não quero chamá-la com function ou algo do genero, a intenção é fazer um método no COM depois que encontre as dlls sozinho.
Bem, eu estou tentando chamar pelo WinExec, com esse código:
WinExec(PChar(´Rundll32.exe Teste.DLL, Confirma ´+cTexto), SW_SHOW);
não dá erro de código, porém ela não traz o resultado que eu espero.
Essa função confirma é para aparecer apenas uma janela perguntando sim ou não. Isso está ok, o que eu não estou conseguindo é mandar o parâmetro de texto corretamente. Ele vai vazio, ou com códigos ou dá o erro: ´Exceção ao tentar executar ´Teste.DLL, Confirma Teste´.
Teste é o texto que eu gostaria que aparecesse.
Enfim, eu preciso de um código onde eu consiga chamar uma dll externa e enviar parametros nela...
Alguém me ajuda.
Gabriela Miglioli
Curtir tópico
+ 0Posts
07/12/2007
Marcosrocha
Se for isso, suponha que você tenha a documentação das funcões da DLL e que ela se chama ConfirmaTexto. Logo você só terá uma declaração da função:
function ConfirmaTexto(Texto: String): Integer; StdCall; External ´TESTE.DLL´;
Gostei + 0
07/12/2007
Brunog3
Gostei + 0
10/12/2007
Gabriela Miglioli
function ConfirmaTexto(Texto: String): Integer; StdCall; External ´TESTE.DLL´;
Bem, na verdade ele tem qua achar a dll... se tiver funções o COM vai olhar isso...
A intenção é fazer o COM olhar no meu banco e definir qual a DLL e a função dela que estou usando... Por isso não posso chamar direto pelo nome da dll, teoricamente, eu não sei o nome dela.
Me passaram isso no final de semana também.
O que está acontecendo agora é que o erro é sempre o mesmo. A mensagem que vem aprarece desconfigurada.
Estou tentando resolver isso... sabe me ajudar??
Obrigada pelo help...
Gostei + 0
12/12/2007
Gabriela Miglioli
Bom, eu consegui mandar os parâmetros para chamar a dll. Usei o LibraryLoad.
Vou postar todo o processo, desde a dll para quem quiser testá-lo.
O código da DLL é algo simples, apenas para teste, mas necessitávamos que ela recebesse um parâmetro string (na verdade vimos que ele deve ser pchar) .
library dlls;
uses
SysUtils, Forms, System, Windows,
Classes, Dialogs;
{$R *.res}
function Confirma(const strTexto: PChar): integer; stdcall ;
begin
Result := Application.MessageBox(strTexto, ´Confirmação´, mb_YesNo+mb_DefButton2+mb_IconQuestion);
end;
exports
Confirma;
end.
A função é simples, como as que vocês provavelmente vão encontrar na maioria dos livros, claro que dá para fazer mais coisas, mas ele serve apenas como teste!!!
O grande ´x´ da questão era como mandar um parâmetro PChar.
Em todos os lugares onde eu pesquisei, a dll é chamada com a Calling Convention (chamada de convenção) usadando stdcall dessa maneira:
function(Texto: PChar): PChar; stdcall;.
Segundo o help do Delphi, há diferenças de uso, e no meu programa não funcionou para um parâmetro pchar. Ele rodava e depois dava o erro de Access Violation.
Então decidi testar com outro e o safecall deu certo. No help ele explica que propriedades como: byte, string, integer, smallint, entre outras devem usar o safecall.
Integer também funciona com stdcall.
Vou mostrar o código de chamada da dll como ficou:
unit Tri;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Spin;
type
FuncaoGenericaQueRecebeEDevolveString = function(Texto: PChar): PChar; safecall;
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
SpinEdit1: TSpinEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
DllName =´dlls.dll´;
procedure TForm1.Button1Click(Sender: TObject);
var
HInst: THandle;
FPointer: TFarProc;
NomeDaFuncao: FuncaoGenericaQueRecebeEDevolveString;
begin
HInst := LoadLibrary(´dlls´);
if HInst > 0 then
try
FPointer := GetProcAddress(HInst, PChar(Edit1.Text));
if FPointer <> nil then
begin
NomeDaFuncao := FuncaoGenericaQueRecebeEDevolveString(FPointer);
Edit2.Text := NomeDaFuncao(´Deu certo!!!!! :D´);
end
else
ShowMessage(Edit1.Text + ´ Função DLL não encontrada´);
finally
FreeLibrary(HInst);
end
else
ShowMessage(´Triplo.dll´ + ´ Biblioteca não encontrada´);
end;
end.
[/color:8b7101ff71]
Gostei + 0
14/12/2007
Silvagpe
bom ...
crie um OBJETO para carregar qualquer DLL
vc passa a os parametros, e ele carrega
espero q ajude ^^
codigo da objeto
unit Objects;
interface
type
TCarregaDll = Class
private
FRoutine : Procedure;
FHandle : THandle;
FRotina: PAnsiChar;
FPathDll: PAnsiChar;
procedure SetPathDll(const Value: PAnsiChar);
procedure SetRotina(const Value: PAnsiChar);
public
procedure loaddll;
property PathDll :PAnsiChar read FPathDll write SetPathDll;
property Rotina :PAnsiChar read FRotina write SetRotina;
End;
implementation
uses
SysUtils,
Windows;
{ TCarregaDll }
procedure TCarregaDll.loaddll;
begin
FHandle := LoadLibrary(FPathDll);
try
FRoutine := GetProcAddress(FHandle,FRotina);
if Assigned(FRoutine) then
FRoutine
else
raise Exception.Create(´Dll não encontrada´);
finally
FreeLibrary(FHandle);
end;
end;
procedure TCarregaDll.SetPathDll(const Value: PAnsiChar);
begin
if Value <>´´ then
FPathDll := Value;
end;
procedure TCarregaDll.SetRotina(const Value: PAnsiChar);
begin
if Value <>´´ then
FRotina := Value;
end;
end.
Código da chama
uses Objects //Declara a unit q tem o Objeto procedure TForm2.Button1Click(Sender: TObject); var CarregaDll : TCarregaDll; begin try CarregaDll := TCarregaDll.Create; CarregaDll.PathDll := ´CriaForm.dll´; CarregaDll.Rotina := ´ChamaForm´; CarregaDll.loaddll; finally CarregaDll.Free; end; end;
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)