GARANTIR DESCONTO

Fórum Como chamar uma dll pelo WinExec, CreateProcess??? #350231

07/12/2007

0

Olá amigos, eu estou com um problemão aqui e gostaria de saber se vocês podem me ajudar.
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

Gabriela Miglioli

Responder

Posts

07/12/2007

Marcosrocha

na verdade você precisa utilizar as funcões de uma DLL?
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´;



Responder

Gostei + 0

07/12/2007

Brunog3

se vc usar o [b:e2a2323eff]LoadLibrary[/b:e2a2323eff] não funciona não?


Responder

Gostei + 0

10/12/2007

Gabriela Miglioli

na verdade você precisa utilizar as funcões de uma DLL? 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´;


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.

se vc usar o [b:18a624e8bd]LoadLibrary[/b:18a624e8bd] não funciona não?

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...


Responder

Gostei + 0

12/12/2007

Gabriela Miglioli

[color=darkred:8b7101ff71]
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]


Responder

Gostei + 0

14/12/2007

Silvagpe

vc quer usa isso para aplicação n-camadas?
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;



Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar