Comando em modo de execução

Delphi

12/06/2007

Bom dia.
Tenho que executar um comando em modo de execução no delphi e não estou conseguindo.

O que preciso é executar um comando que está em uma string, por exemplo, em um Edit eu tenho o comando close; digitado, e ao pressionar um botão, o delphi execute o comando que está neste edit.

Supondo algo parecido como: execute(edit1.text); é a mesma coisa do delphi chamar diretamente close;

Preciso que a funcionalidade funcione também com chamadas a procedures e funções.

Em VB, PHP, ASP eu sei que existe esta possibilidade, mas em Delphi eu não encontrei nada parecido.

Preciso desta funcionalidade para implementar uma rotina complexa aqui no meu serviço... se funcionar como o exemplo acima irá funcionar na minha rotina.


Mlferreira

Mlferreira

Curtidas 0

Respostas

Mlferreira

Mlferreira

12/06/2007

Vou explicar realmente o que preciso, é meio confuso mas vamos lá...

No sistema comercial de nossa empresa, está sendo apendado uma tela de pesagem, que utiliza algumas rotinas de comunicação com a balança (toledo)
O Fabricante disponibiliza junto com a balança, uma DLL que faz a comunicação via Serial, e junto um Hardlock com 3 licenças de uso.
O Correto seria consumir 1 licença somente quando a função Leitura fosse executada, dentro da tela de pesagem. Mas isto não está ocorrendo. Pelo simples fato de estar referenciando a chamada da função no forms da balança, esta ativação da licença é startada antes mesmo de dar o Application.CreateForm.
Portanto o que eu quero tentar fazer é inibir a chamada da função de forma direta, ao invés de deixar a chamada explícita ret := Comunica(1); eu estou tentando criar a chamada em modo de execução, e uma maneira que me veio a cabeça é executá-la dinamicamente por exemplo executa(´ret := Comunica(1)´); Pois assim a chamada não fica referenciada no meu sistema, e os demais usuários que utilizam o sistema comercial, e não utilizam a tela da balança, não consomem as licenças.


GOSTEI 0
Massuda

Massuda

12/06/2007

Provavelmente a validação do hardlock está sendo feita quando a DLL é carregada. Para fazer com que apenas o usuário que precisa da balança carregue a DLL, use carregamento dinâmico da DLL. Veja por exemplo, este tópico no fórum...

http://forum.devmedia.com.br/viewtopic.php?t=83183


GOSTEI 0
Mlferreira

Mlferreira

12/06/2007

type
  TfncCnx = function (s : string) : THandle;

var
  cnx : TfncCnx;
  h,x:  THandle;
  Nome,ver,serial,Conex,Programa : PChar;
begin
  { load the DLL and get the function´s address }
  h := LoadLibrary(pclink6.dll);
  if h = 0 then
  begin
    ShowMessage (´DLL not available´);
  end
  else
  begin
    @cnx := GetProcAddress(h, ´FirVer´);
    if @cnx = nil then 
    begin
      { function not found.. misspelled? }
      ShowMessage (´blub´);
    end
else
    begin
      { call the function as usually }
      x := cnx(FirVer(Nome,ver,serial,Conex,Programa));
    end;
    { unload the DLL }
    FreeLibrary(h);
  end;
end;


É não deu certo.... está dando Acess Violation e trava tudo.
Alguma idéia?


GOSTEI 0
Mlferreira

Mlferreira

12/06/2007

Deu certo agora, precisei mudar algumas coisinhas, segue o código adaptado.

type
  // Chamadas dinâmicas as funções da PClink6.dll
  TFirVer       = procedure(var Nome,ver,serial,Conex,Programa : PChar); stdcall;
  TW9091Serial  = function (Canal : Integer): Integer; stdcall;
  TSelect_Canal = function (CANAL_SETADO : Integer) : integer; stdcall;
  TUpdate_Canal = function (Canal : integer) : Integer; stdcall;
  TGross_Canal  = function (Canal : integer) : PChar; stdcall;
  TClose_Canal  = procedure(Canal : integer); stdcall;
  TDeleta_Canal = procedure(Canal : integer); stdcall;
...


var
  fmCOM0087: TfmCOM0087;
  DLL : integer;
implementation
...


procedure TfmCOM0087.tConexaoBalTimer(Sender: TObject);
var
  GetFirVer       : TFirVer;
  GetW9091Serial  : TW9091Serial;
  Nome,ver,serial,Conex,Programa : PChar;
begin

  // Carrega o Endereço de memória da função/procedure na dll
  @GetFirVer := GetProcAddress(DLL, ´FirVer´);

  // Executa a função/procedure
  GetFirVer(Nome,ver,serial,Conex,Programa);
....


// outro exemplo de chamada..
    @GetSelect_Canal := GetProcAddress(DLL, ´Select_Canal´);
    if GetSelect_Canal(CanalSelecionado) = 0 then
...


Estava dando erro pois não tinha setado os parâmetros corretamente para a função.
[/code]


GOSTEI 0
Guilherme Souza

Guilherme Souza

12/06/2007

Deu certo agora, precisei mudar algumas coisinhas, segue o código adaptado.

type
  // Chamadas dinâmicas as funções da PClink6.dll
  TFirVer       = procedure(var Nome,ver,serial,Conex,Programa : PChar); stdcall;
  TW9091Serial  = function (Canal : Integer): Integer; stdcall;
  TSelect_Canal = function (CANAL_SETADO : Integer) : integer; stdcall;
  TUpdate_Canal = function (Canal : integer) : Integer; stdcall;
  TGross_Canal  = function (Canal : integer) : PChar; stdcall;
  TClose_Canal  = procedure(Canal : integer); stdcall;
  TDeleta_Canal = procedure(Canal : integer); stdcall;
...
Por acaso você tem o exemplo disso funcionando para me enviar? Estou tentando ler o peso da balança utilizando a dll mas não estou conseguindo.
Fico grato.
guilherme@info04informatica.com.br

var
  fmCOM0087: TfmCOM0087;
  DLL : integer;
implementation
...


procedure TfmCOM0087.tConexaoBalTimer(Sender: TObject);
var
  GetFirVer       : TFirVer;
  GetW9091Serial  : TW9091Serial;
  Nome,ver,serial,Conex,Programa : PChar;
begin

  // Carrega o Endereço de memória da função/procedure na dll
  @GetFirVer := GetProcAddress(DLL, ´FirVer´);

  // Executa a função/procedure
  GetFirVer(Nome,ver,serial,Conex,Programa);
....


// outro exemplo de chamada..
    @GetSelect_Canal := GetProcAddress(DLL, ´Select_Canal´);
    if GetSelect_Canal(CanalSelecionado) = 0 then
...


Estava dando erro pois não tinha setado os parâmetros corretamente para a função.
[/code]


GOSTEI 0
POSTAR