Compilar função em tempo de execução

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

Claudio Soto
Colaborador
Colaborador
Mensagens: 566
Registrado em: 27 Ago 2012 12:31
Localização: Uruguay
Contato:

Compilar função em tempo de execução

Mensagem 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.
Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
Avatar do usuário
dbsh
Usuário Nível 3
Usuário Nível 3
Mensagens: 128
Registrado em: 14 Jul 2004 14:19
Localização: ES

Compilar função em tempo de execução

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


010011110010000001110011011101010110001101100101011100110111001101101111001000001110100100100000011000110110111101101110011100110111010001110010011101011110110101100100011011110010000001100001001000000110111001101111011010010111010001100101
01001101011000010111001001100011011011110111001100100000010000010110111001110100011011110110111001101001011011110010000001000100011001010010000001000010011011110110111001101001
0101010001100101011011000011101000100000001010000011001000110111001010010011100100101101001110010011100000110100001100110010110100110101001100100011100100110000
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Compilar função em tempo de execução

Mensagem 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()?.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Claudio Soto
Colaborador
Colaborador
Mensagens: 566
Registrado em: 27 Ago 2012 12:31
Localização: Uruguay
Contato:

Compilar função em tempo de execução

Mensagem 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>
Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
Avatar do usuário
dbsh
Usuário Nível 3
Usuário Nível 3
Mensagens: 128
Registrado em: 14 Jul 2004 14:19
Localização: ES

Compilar função em tempo de execução

Mensagem por dbsh »

Jairo, parti do principio o que disse "Claudio Soto", não testei outras combinações, só as que precisei
010011110010000001110011011101010110001101100101011100110111001101101111001000001110100100100000011000110110111101101110011100110111010001110010011101011110110101100100011011110010000001100001001000000110111001101111011010010111010001100101
01001101011000010111001001100011011011110111001100100000010000010110111001110100011011110110111001101001011011110010000001000100011001010010000001000010011011110110111001101001
0101010001100101011011000011101000100000001010000011001000110111001010010011100100101101001110010011100000110100001100110010110100110101001100100011100100110000
frazato
Usuário Nível 3
Usuário Nível 3
Mensagens: 219
Registrado em: 08 Jul 2004 07:45

Compilar função em tempo de execução

Mensagem 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
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Compilar função em tempo de execução

Mensagem por Jairo Maia »

Olá Pessoal,

Dr Soto, obrigado pelas explicações, ficou bem claro. Marcos, obrigado, valeu...
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
frazato
Usuário Nível 3
Usuário Nível 3
Mensagens: 219
Registrado em: 08 Jul 2004 07:45

Compilar função em tempo de execução

Mensagem por frazato »

Bom dia!
Fiz uns testes simples e funcionou, gostaria de saber se existe isso no xharbour( Ainda uso rss).

Frazato
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Compilar função em tempo de execução

Mensagem por asimoes »

Frazato,

Se não me engano este recurso é exclusivo do harbour. xHarbour parou de acompanhar as inovações do harbour.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Compilar função em tempo de execução

Mensagem 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
[]´s
Alexandre Santos (AlxSts)
frazato
Usuário Nível 3
Usuário Nível 3
Mensagens: 219
Registrado em: 08 Jul 2004 07:45

Compilar função em tempo de execução

Mensagem 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
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Compilar função em tempo de execução

Mensagem 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
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
dbsh
Usuário Nível 3
Usuário Nível 3
Mensagens: 128
Registrado em: 14 Jul 2004 14:19
Localização: ES

Compilar função em tempo de execução

Mensagem 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
010011110010000001110011011101010110001101100101011100110111001101101111001000001110100100100000011000110110111101101110011100110111010001110010011101011110110101100100011011110010000001100001001000000110111001101111011010010111010001100101
01001101011000010111001001100011011011110111001100100000010000010110111001110100011011110110111001101001011011110010000001000100011001010010000001000010011011110110111001101001
0101010001100101011011000011101000100000001010000011001000110111001010010011100100101101001110010011100000110100001100110010110100110101001100100011100100110000
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Compilar função em tempo de execução

Mensagem por fladimir »

Obrigado pelo feedback.
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Compilar função em tempo de execução

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder