Instanciar HModule e não liberar
O problema é que, ao carregar um módulo eu faço assim:
(resumidamente, sem os tratamentos)
acontece que o modulo pertence ao escopo deste procedimento (onclick por exemplo) e o mesmo é liberado ao término da execução (aparentemente).
no meu caso eu preciso carregar vários modulos, mas não tem um número fixo, o que eu não poderia declarar N variávels do tipo HModule, pois esse numero vai variar.
Pensei em usar um array, mas não sei se é correto; ou ponteiros?
abraços
(resumidamente, sem os tratamentos)
... var modulo : Hmodule; proc : procedure; modulo := LoadPackage(´modulo.bpl´); @proc := GetProcAddress(modulo, ´ProcedimentoExportado´); proc; end;
acontece que o modulo pertence ao escopo deste procedimento (onclick por exemplo) e o mesmo é liberado ao término da execução (aparentemente).
no meu caso eu preciso carregar vários modulos, mas não tem um número fixo, o que eu não poderia declarar N variávels do tipo HModule, pois esse numero vai variar.
Pensei em usar um array, mas não sei se é correto; ou ponteiros?
abraços
Eniorm
Curtidas 0
Respostas
Eniorm
19/05/2008
sobe
GOSTEI 0
Massuda
19/05/2008
Não entendi... você está afirmando que modulo.bpl está sendo liberado porque modulo:HModule saiu de escopo? Isso não acontece.
GOSTEI 0
Eniorm
19/05/2008
pelo que aprendi, as variáveis declaradas num escopo, por ex, no onclick, ao terminar essas variáveis são liberadas...
por exemplo esse modulo : HModule, eu armazeno o handle dele (cardinal) num stringlist
ao termino do programa eu libero manualmente assim
if (Modulo <> Nil) then
UnLoadPackage(Modulo)
no entando se eu omitir o if e usar UnLoadPackage diretamente da erro pois o módulo foi liberado.
isso só funciona com as variaveis hmodule declaradas por exemplo na sessão public de minha unit, elas permanecem instanciadas até o termino do meu programa, já as declaradas dentro do escopo no meu procedimento essas depois da execução do procedimento nao permaneceram instanciadas
abraços
por exemplo esse modulo : HModule, eu armazeno o handle dele (cardinal) num stringlist
ao termino do programa eu libero manualmente assim
if (Modulo <> Nil) then
UnLoadPackage(Modulo)
no entando se eu omitir o if e usar UnLoadPackage diretamente da erro pois o módulo foi liberado.
isso só funciona com as variaveis hmodule declaradas por exemplo na sessão public de minha unit, elas permanecem instanciadas até o termino do meu programa, já as declaradas dentro do escopo no meu procedimento essas depois da execução do procedimento nao permaneceram instanciadas
abraços
GOSTEI 0
Massuda
19/05/2008
[quote:9567b038d0=´Enio Marconcini´]já as declaradas dentro do escopo no meu procedimento essas depois da execução do procedimento nao permaneceram instanciadas[/quote:9567b038d0]Sim, são variáveis locais que saem do escopo quando termina a função. Se você quer armazenar o HModule das BPLs que carregar, você precisa manter uma lista ou array (dinamico) que deve ser um membro da classe ou uma variável global da unit ou programa.
GOSTEI 0
Eniorm
19/05/2008
você precisa manter uma lista ou array (dinamico) que deve ser um membro da classe ou uma variável global da unit ou programa.
então rsrsrs :D é esse mesmo o meu problema até o momento eu não cheguei numa conclusão o que seria melhor usar uma lista ou um array dinâmico,
estou pesquisando como trabalhar com tais listas/arrays e confesso que estou apanhando um pouco.
nao sei ainda como ir adicionando dinamicamente cada modulo no array
abraço
GOSTEI 0
Emerson Nascimento
19/05/2008
[quote:bebc1b283c=´Enio Marconcini´]...ao termino do programa eu libero manualmente assim
if (Modulo <> Nil) then
UnLoadPackage(Modulo)...[/quote:bebc1b283c]
quando você diz ´ao término do programa´, você quer dizer do programa mesmo ou o uso do pacote?
if (Modulo <> Nil) then
UnLoadPackage(Modulo)...[/quote:bebc1b283c]
quando você diz ´ao término do programa´, você quer dizer do programa mesmo ou o uso do pacote?
GOSTEI 0
Eniorm
19/05/2008
qdo o programa é encerrado mesmo.
Outro detalhe: eu uso forms MDI
fiz um teste ontem e notei que
1- após abrir o programa, e carregar o modulo e disparar o evento, eu consigo por exemplo trocar o nome ou até apagar o modulo carregado
2- apos, posso chamar novamente o evento que continua abrindo o form, mesmo o modulo ter sido apagado.
rsrsrs
Outro detalhe: eu uso forms MDI
fiz um teste ontem e notei que
1- após abrir o programa, e carregar o modulo e disparar o evento, eu consigo por exemplo trocar o nome ou até apagar o modulo carregado
2- apos, posso chamar novamente o evento que continua abrindo o form, mesmo o modulo ter sido apagado.
rsrsrs
GOSTEI 0
Emerson Nascimento
19/05/2008
você diz que consegue apagar fisicamente o arquivo bpl? e ainda assim o form contido nele é aberto?
tem certeza que seu projeto está modularizado?
se você fechar o sistema (estando o bpl apagado) e abri-lo novamente, ao chamar o form que deveria estar no bpl, ainda assim ele abre?
entendeu o que eu disse?
1 - feche o sistema
2 - apague o bpl
3 - abra o sistema
4 - execute a opção que abre o form
funciona?
tem certeza que seu projeto está modularizado?
se você fechar o sistema (estando o bpl apagado) e abri-lo novamente, ao chamar o form que deveria estar no bpl, ainda assim ele abre?
entendeu o que eu disse?
1 - feche o sistema
2 - apague o bpl
3 - abra o sistema
4 - execute a opção que abre o form
funciona?
GOSTEI 0
Eniorm
19/05/2008
tem certeza que seu projeto está modularizado?
rsrsrs sim, está modularizado, o único vinculo que existe em a aplicação principal e os módulos é o [b:f81b9033f4]LoadPackage[/b:f81b9033f4]
se você fechar o sistema (estando o bpl apagado) e abri-lo novamente, ao chamar o form que deveria estar no bpl, ainda assim ele abre?
ai não, da erro na hora do LoadPackage pois não consegue localizar o pacote.bpl...
o estranho é que se seguir essa ordem, funciona:
1) abro o programa, clico no item de menu que abre um form que fica dentro do modulo.bpl. Os códigos são usados os que acima eu informei, resumidamente.
2) tanto faz eu deixar aberto ou fechar este form, eu posso ir na pasta onde está o exe e os bpls que eu consigo renomear ou apagar o modulo.bpl
3) o item do menu continua funcionando mesmo com o bpl excluído.
4) se eu fechar o programa, ai na proxima vez gera o erro caso o pacote não estiver presente.
a variável onde eu instancio o HModule pertence ao escopo da implementação do evento OnClick deste item de menu. A variável tipo procedure tbm pertence a este escopo.
muito estranho, não? rsrsr
GOSTEI 0
Eniorm
19/05/2008
up... :D
GOSTEI 0
Eniorm
19/05/2008
wana-wanga!!!
amigos, achei uma solução da seguinte forma para o meu problema,
dessa forma eu tenho um vetor dinâmico do meu tipo TModulo...
[b:bd1ef9aa94]cada módulo é instanciado assim:[/b:bd1ef9aa94]
[b:bd1ef9aa94]para abrir um método implementado dentro de um módulo bpl eu faço assim[/b:bd1ef9aa94]
[b:bd1ef9aa94]no momento em que eu preciso abrir um método eu faço:[/b:bd1ef9aa94]
[i:bd1ef9aa94]por exemplo no onClick qualquer[/i:bd1ef9aa94]
analisando a implementação dos métodos AbreModulo e CarregaMetodo da pra ver que pode ser melhorado.
Eu uso o FOR para pesquisar pelo vetor pois não sei se o Delphi existe alguma função ou procedimento mais útil para pesquisar itens num vetor.
nos códigos acima eu, para resumir, não inclui os tratamentos de exceções que por ventura possa acontecer caso dê algum erro na hora de carregar o módulo ou uma tentativa de chamada de método inexistente.
Espero que possa ajudar os outros necessitados rsrsrsrs :D
amigos, achei uma solução da seguinte forma para o meu problema,
... type TModulo = record Bpl : String; Modulo : HModule; end; var ModulosCarregados : array of TModulo; ...
dessa forma eu tenho um vetor dinâmico do meu tipo TModulo...
[b:bd1ef9aa94]cada módulo é instanciado assim:[/b:bd1ef9aa94]
procedure AbreModulo(Bpl : String); var I, Posicao : SmallInt; begin // pra saber se o modulo já foi instanciado Posicao := -1; for I := Low(ModulosCarregados) to High(ModulosCarregados) do if (ModulosCarregados[I].Bpl = Bpl) then Posicao := I; // instancia caso não tenha encontrado if (Posicao = -1) then begin I := Length(ModulosCarregados); SetLength(ModulosCarregados,I+1); ModulosCarregados[I].Bpl := Bpl; ModulosCarregados[I].Modulo := LoadPackage(Bpl); end; end;
[b:bd1ef9aa94]para abrir um método implementado dentro de um módulo bpl eu faço assim[/b:bd1ef9aa94]
procedure CarregaMetodo(Bpl, Metodo : String; var Implementacao : Pointer); var I, Posicao : SmallInt; begin // novamente pra saber a posicao do modulo no vetor Posicao = -1; for I := Low(ModulosCarregados) to High(ModulosCarregados) do if (ModulosCarregados[I].Bpl = Bpl) then begin Posicao := I; Exit; // para sair do IF e do LAÇO ??? end; // agora eu carrego o método solicitado if (Posicao > -1) then implementacao := GetProcAddress(ModulosCarregados[Posicao].Modulo,Metodo); end;
[b:bd1ef9aa94]no momento em que eu preciso abrir um método eu faço:[/b:bd1ef9aa94]
[i:bd1ef9aa94]por exemplo no onClick qualquer[/i:bd1ef9aa94]
... var proc : procedure; begin AbreModulo(´clientes.bpl´); CarregaMetodo(´clientes.bpl´,´cadastroclientes´,@proc); proc; end;
analisando a implementação dos métodos AbreModulo e CarregaMetodo da pra ver que pode ser melhorado.
Eu uso o FOR para pesquisar pelo vetor pois não sei se o Delphi existe alguma função ou procedimento mais útil para pesquisar itens num vetor.
nos códigos acima eu, para resumir, não inclui os tratamentos de exceções que por ventura possa acontecer caso dê algum erro na hora de carregar o módulo ou uma tentativa de chamada de método inexistente.
Espero que possa ajudar os outros necessitados rsrsrsrs :D
GOSTEI 0