Comando em modo de execução
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.
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
Curtidas 0
Respostas
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.
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
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
http://forum.devmedia.com.br/viewtopic.php?t=83183
GOSTEI 0
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
12/06/2007
Deu certo agora, precisei mudar algumas coisinhas, segue o código adaptado.
Estava dando erro pois não tinha setado os parâmetros corretamente para a função.
[/code]
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
12/06/2007
Deu certo agora, precisei mudar algumas coisinhas, segue o código adaptado.
Estava dando erro pois não tinha setado os parâmetros corretamente para a função.
[/code]
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