Página 2 de 2
Compilar função em tempo de execução
Enviado: 11 Abr 2016 00:05
por Claudio Soto
En resumen, hay que pensar en hb_CompileFromBuf() coma una extensión de la macro sustitucion (&cPRGCode) en tiempo de ejecución, por ejemplo:
Código: Selecionar todos
LOCAL cPRGCode, cByteCode
LOCAL cText := "Hola Mundo"
cPRGCode := "#DEFINE MI_MSG ' Cruel'" + Hb_EoL()
cPRGCode += "Procedure MiMensaje( cMsg )" + Hb_EoL()
cPRGCode += " MsgInfo( cMsg + MI_MSG )" + Hb_EoL()
cPRGCode += "Return"
// &cPRGCode --> este codigo con macro sustitucion no funciona
cByteCode := hb_CompileFromBuf( cPRGCode, "harbour", "/n" )
hb_hrbRun( cByteCode, cText ) // equivale a --> MiMensaje( cText )
este código no funciona con macro sustitucion (&cProc) pero si con hb_CompileFromBuf(), y si embutimos los #define en el código no necesitamos de los archivos de cabecera.
En la practica, hb_CompileFromBuf() es util para crear trozos de código complejo que no puede ser compilado y ejecutado a runtime con la macro sustitucion.
Compilar função em tempo de execução
Enviado: 12 Abr 2016 08:00
por dbsh
Para suporte remoto, atualização remota, é excelente, utilizo também na minha rotina de menu, para mudar somente uma opção, temporariamente, sem ter que atualizar o executável.
EX:
Código: Selecionar todos
IF File('op_' + StrTrim(nNivelAcesso) + '.hrb')
CmdExecuta('op_' + StrTrim(nNivelAcesso) + '.hrb')
ELSE
uRet := Eval(MenuOpcao[nNivelAcesso])
ENDIF
//retirado da minha LIB
'FUNCTION CmdExecutaHRB( cFileName, nOp )
LOCAL buf
DEFAULT nOp TO 2
IF File(cFileName) //USANDO .hrb
Buf = HB_HRBLOAD(nOp, cFileName )
IF Empty( Buf )
RETURN .F.
ENDIF
HB_HRBDO( Buf )
HB_HRBUNLOAD( Buf )
ELSE
RETURN .F.
ENDIF
RETURN .T.
FUNCTION CmdExecutaPRG( cFileName, nOp )
LOCAL Buf
DEFA nOp To 2
IF File(cFileName) //USANDO .prg
//hb_compile( "harbour", cFileName, "/n","/w", "/gh" ) // Compile, e gera .hrb
buf := hb_compilebuf( "harbour", cFileName, "/n", "/w", "/q2" ) // Compile
IF Empty( Buf )
RETURN .F.
ENDIF
hb_hrbRun( buf ) //execute
/*
Buf = HB_HRBLOAD(nOp, Buf )
IF Empty( Buf )
RETURN .F.
ENDIF
HB_HRBDO( Buf )
HB_HRBUNLOAD( Buf )
*/
ELSE
RETURN .F.
ENDIF
RETURN .T.
FUNCTION CmdExecutaVar( sVar, nOp )
LOCAL Buf
DEFA nOp To 2
IF Upper(Left(sVar, 5)) = "/VAR:" //USANDO variavel
sVar := SubStr(sVar, 6)
ENDIF
Buf := hb_compileFromBuf( sVar, "/n", "/m", "/q2" )
IF Empty( Buf )
RETURN .F.
ENDIF
hb_hrbRun( buf ) //execute
/*
Buf = HB_HRBLOAD(nOp, Buf )
IF Empty( Buf )
RETURN .F.
ENDIF
HB_HRBDO( Buf )
HB_HRBUNLOAD( Buf )
*/
RETURN .T.
FUNCTION CmdExecuta( cFileName, nOp )
DEFA nOp TO 2 //0 e 1 - Executavel, 2 - Arquivo/Variavel
IF !File(cFileName)
IF ("." $ cFileName)
RETURN .F.
ELSE
IF File(cFileName + '.hrb')
cFileName += ".hrb"
ELSEIF File(cFileName + '.prg')
cFileName += ".prg"
ELSEIF File(cFileName + '.cmd')
cFileName += ".cmd"
ELSE
RETURN .F.
ENDIF
ENDIF
ENDIF
IF Upper(Right(cFileName, 4)) = '.CMD'
cFileName := "/VAR:" + Cript(FileRead(cFileName))
ENDIF
IF Upper(Left(cFileName, 5)) = "/VAR:"
CmdExecutaVar(cFileName, nOp)
ELSEIF Upper(Right(cFileName, 4)) = '.HRB'
CmdExecutaHRB(cFileName, nOp)
ELSE
CmdExecutaPRG(cFileName, nOp)
ENDIF
RETURN .T.
FUNCTION CmdCriaHRB( cFileName )
LOCAL Buf
IF File(cFileName)
Buf := hb_compile( "harbour", cFileName, "/n","/w", "/q2", "/gh" ) // Compile, e gera .hrb
IF Empty( Buf )
RETURN .F.
ENDIF
ELSE
RETURN .F.
ENDIF
RETURN .T.
Compilar função em tempo de execução
Enviado: 12 Abr 2016 10:40
por Jairo Maia
Olá Marcos,
Embora seu código está muito bem comentado, você ou algum colega teria como indicar onde encontrar os parâmetros suportados pela função Hb_CompileFromBuf()?.
Compilar função em tempo de execução
Enviado: 12 Abr 2016 11:00
por Claudio Soto
Jairo Maia escreveu:Olá Marcos,
Embora seu código está muito bem comentado, você ou algum colega teria como indicar onde encontrar os parâmetros suportados pela função Hb_CompileFromBuf()?.
Jairo,
no hice los test necesarios, pero supongo que soporta todos o al menos la mayoría de los parámetros del compilador ( c:\HB32\bin\harbour.exe )
Código: Selecionar todos
Harbour 3.2.0dev (r1509031202)
Copyright (c) 1999-2015, http://harbour-project.org/
Syntax: harbour <file[s][.prg]|@file> [options]
Options: -a automatic memvar declaration
-b debug info
-build display detailed version info
-credits display credits
-d<id>[=<val>] #define <id>
-es[<level>] set exit severity
-fn[:[l|u]|-] set filename casing (l=lower u=upper)
-fd[:[l|u]|-] set directory casing (l=lower u=upper)
-fp[:<char>] set path separator
-fs[-] turn filename space trimming on or off (default)
-g<type> output type generated is <type> (see below)
-gc[<type>] output type: C source (.c) (default)
<type>: 0=compact (default) 1=normal 2=verbose
3=generate real C code
-gh output type: Harbour Portable Object (.hrb)
-gd[.<destext>] generate dependencies list into (.d) file
-ge[<mode>] error output <mode>: 0=Clipper (default)
1=IDE friendly
-i<path> #include file search path
-i[-|+] disable/enable support for INCLUDE envvar
-j[<file>] generate i18n gettext file (.pot)
-k compilation mode (type -k? for more data)
-l suppress line number information
-m compile module only
-n[<type>] no implicit starting procedure
<type>: 0=no implicit starting procedure
1=no starting procedure at all
2=add starting procedure if necessary
-o<path> object file drive and/or path
-p[<path>] generate pre-processed output (.ppo) file
-p+ generate pre-processor trace (.ppt) file
-q quiet
-q0 quiet and don't display program header
-q2 disable all output messages
-ql hide line counter gauge
-r:<max> set maximum number of preprocessor iterations
-s[m] syntax check only [minimal for dependencies list]
-u[<file>] use command def set in <file> (or none)
-u+<file> add command def set from <file>
-undef:<id> #undef <id>
-v variables are assumed M->
-w[<level>] set warning level number (0..3, default 1)
-z suppress shortcutting (.and. & .or.)
@<file> compile list of modules in <file>
Compilar função em tempo de execução
Enviado: 13 Abr 2016 06:56
por dbsh
Jairo, parti do principio o que disse "Claudio Soto", não testei outras combinações, só as que precisei
Compilar função em tempo de execução
Enviado: 13 Abr 2016 12:03
por frazato
Bom dia! já tentei usar esse recurso mais, como utilizo recurso da Gtwvw e funções tipo menus e relatorios, não consigo executar, executo apenas rotinas pura em xharbour ou tenho que fazer todas as telas ou colocar tudo dentro de uma unico PRG ( isso ainda não teste), vc teria alguma exemplo de como montar um relatorio dentro do PRG e executar o mesmo usando rotinas/funções dentro do executável?
Frazato
Compilar função em tempo de execução
Enviado: 13 Abr 2016 16:50
por Jairo Maia
Olá Pessoal,
Dr Soto, obrigado pelas explicações, ficou bem claro. Marcos, obrigado, valeu...
Compilar função em tempo de execução
Enviado: 14 Abr 2016 10:46
por frazato
Bom dia!
Fiz uns testes simples e funcionou, gostaria de saber se existe isso no xharbour( Ainda uso rss).
Frazato
Compilar função em tempo de execução
Enviado: 14 Abr 2016 11:16
por asimoes
Frazato,
Se não me engano este recurso é exclusivo do harbour. xHarbour parou de acompanhar as inovações do harbour.
Compilar função em tempo de execução
Enviado: 14 Abr 2016 14:39
por alxsts
Olá!
Existe alguma coisa parecida mas as funções tem outros nomes. Segue exemplo extraído do manual xHarbour Language Reference Guide:
Código: Selecionar todos
// The example outlines two possibilities of calling a function
// indirectly via macro expression. The first compiles a macro
// to PCode, and the second creates a code block with the macro
// operator. Note that functions that are only included in macro
// expressions should be REQUESTed to make sure they are linked.
REQUEST QOut, Time
PROCEDURE Main
LOCAL cMacro := "QOut( Time() )"
LOCAL cPCode := HB_MacroCompile( cMacro )
LOCAL bBlock := &( "{||" + cMacro + "}" )
HB_VMExecute( cPCode )
EVal( bBlock )
RETURN
Compilar função em tempo de execução
Enviado: 14 Abr 2016 15:10
por frazato
Boa tarde!
Fiz o teste funciona, mais não consegui fazer funcionar utilizando o PRG com funções já dentro do executável, tipo faço um relatório e apenas ajusto colunas e uso todo o recurso de impressão/visualização do executável principal, inclusive caixa de texto e botões.
Frazato
Compilar função em tempo de execução
Enviado: 16 Mai 2016 11:49
por fladimir
O colega DBSH comentou que:
Para suporte remoto, atualização remota, é excelente,
Alguém tem ideia de como seria isso através dessa funcionalidade?
[]´s
Compilar função em tempo de execução
Enviado: 19 Mai 2016 00:38
por dbsh
Utilizo tres executáveis:
Monitor.exe, Atualiza.exe e Sogec.exe
três PRG Fixos:
sogec_init.cmd, sogec_w_s.cmd e sogec_v_s.cmd
três PRG Temporario:
sogec_init_tmp.cmd, sogec_w_s_tmp.cmd e sogec_v_s_tmp.cmd
e os arquivos:
sogec_init.ini, sogec_w_s.ini e sogec_v_s.ini
sogec_init_tmp.ini, sogec_w_s_tmp.ini e sogec_v_s_tmp.ini
Monitor.exe procura periodicamente por atualização no servidor web na pasta privada do cliente e na pasta publica para todos clientes, executáveis e PRG, e disponibiliza na pasta local de trabalho.
utilizo a monenclatura "programa.atu.exe" para sobrepor a versão anterior, e "programa.new.exe" para preservar a versão anterior ate 4 versões (configuráveis)
Não chamo o executável do meu sistema diretamente, chamo atualiza.exe, ele procura por atualização na pasta de trabalho e atualiza a versão.
As rotinas "prg" são criptografada, e chamado por sogec.exe, assim posso usar todos as rotinas do sistema sem ter que reprogramar de novo.
No inicio do sistema antes de fazer qualquer coisa, se existir executa: SOGEC_INIT.CMD e SOGEC_INIT_TMP.CMD
Antes de digitar a senha após ter inicializado e configurado o sistema com a senha padrão, se existir executa: SOGEC_W_S.CMD e SOGEC_W_S_TMP.CMD
Após o usuário ter digitado a senha, e ter reconfigurado o sistema para senha em uso, se existir executa: SOGEC_V_S.CMD e SOGEC_V_S_TMP.CMD
os arquivos: sogec_init.ini, sogec_w_s.ini, sogec_v_s.ini, sogec_init_tmp.ini, sogec_w_s_tmp.ini e sogec_v_s_tmp.ini
tem informações para orientar como proceder em caso de erro ou se for tudo ok, podendo ser excluídos ou não
os arquivos sogec_*_tmp.cmd serão excluidos após executados sem erro, ou não se der erro:
Posso atualizar a versão, enviar arquivos PRG, ou os dois
o arquivo Atualiza.exe é atualizado pelo sogec.exe
Meu sistema de menu, utiliza um ID, único para cada opção, uso isto para enviar um PRG, e usar somente naquela opção, e corrigir uma opção com erro.
EX: OP_234.cmd
Compilar função em tempo de execução
Enviado: 19 Mai 2016 11:53
por fladimir
Obrigado pelo feedback.
Compilar função em tempo de execução
Enviado: 19 Mai 2016 12:11
por JoséQuintas
Pra esse tipo de coisa me pareceu complicação demais.
Eu deixo toda e qualquer mudança dentro do EXE normal, porque geralmente se precisou resolver problema em um, teria que resolver no outro.
Até pra controle fica mais interessante.
Código: Selecionar todos
IF cVersao < 20160519
RotinadeConversao()
NovoAcesso( "RELATORIO_GERAL" )
IF cEmpresaApelido == "umcliente"
NovoAcesso( "RELATORIO_ADM", "OPC_GERENTE" )
NovoAcesso( "RELATORIO_EXCLUSIVO", "ANTONIO" )
ENDIF
ENDIF
No cliente, ele só clica em atualizar.
E dependendo do tipo de atualização, removo depois se não for mais necessária.
Não lembro de ter precisado disto, mas vai que um cliente precise retornar um backup, já fica tudo resolvido.