Usar uma DLL externa

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
Clipper
Colaborador
Colaborador
Mensagens: 1334
Registrado em: 23 Ago 2004 00:04
Localização: Recife/PE

Usar uma DLL externa

Mensagem por Clipper »

Boa noite prezados colegas.

Alguém tem um exemplo prático de como fazer uso de uma DLL externa com o Harbour ?


Obrigado e até logo.

Marcelo
Programador que é programador, quando tá de folga vai inventar função nova, fazer testes, ou seja... se divertir
Cobra 210 - Drive de 8" 1.024 KB - 64 KB RAM - Impressora de Linha Cobra - Visicalc - Fortran - Dialog - Sistema Operacional SP/M (é sp/m mesmo - era o cp/m da cobra)
Avatar do usuário
janio
Colaborador
Colaborador
Mensagens: 1846
Registrado em: 06 Jul 2004 07:43
Localização: UBAJARA - CE

Usar uma DLL externa

Mensagem por janio »

nDll := dllload("Bemafi32.dll")
oRet := DllCall( nDll, 32, "Bematech_FI_DownloadMF", "C:\CriaSoftWare\" + ArquivoDestino )

If oRet != 1
MsgErro()
Endif

DllUnload( nDll )
fui...
e-mail:janioaguiar@yahoo.com.br
msn: janio_aguiar@hotmail.com
xHarbour1.2.1/Harbour3.2 + wvg + hwgui + Mediator + MySql
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usar uma DLL externa

Mensagem por JoséQuintas »

Jãnio, se não me engano isso faz parte da compatibilidade com xHarbour, não sei se prefere a função direta do Harbour.

Como exemplo, pra pegar o usuário do Windows:

Código: Selecionar todos

FUNCTION mywin_GetUserName()

   LOCAL cUserName := Space(255), nSize := 250

   CallDll( "GetUserNameA", "advapi32.dll", @cUserName, @nSize )
   RETURN AllTrim( cUserName )
No Harbour 3.2 é CallDll32(), e no Harbour 3.4 é CallDll()

Quanto às variáveis, tudo está relacionado com as funções da DLL.

Tem casos em que o parâmetro é do tipo "pointer", igual acima, algo como passar a localização dentro da memória.
Nestes casos o tamanho faz diferença, senão causa GPF porque o resultado pode invadir memória que não deveria..
Nestes casos, é obrigatório passar por referência.

Tem casos aonde é a variável comum, porque vai ser passado somente o conteúdo dela.

E a chamada de DLL também pode retornar um valor.
x = CallDll(...)

Se os parâmetros não estiverem de acordo, tipo de variável/parâmetro, pode gerar GPF.
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/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

Código: Selecionar todos

#include "hbdyn.ch"
FUNCTION BaixarURLMON
   nHandleDLL:=hb_LibLoad("UrlMon.dll")
   nStatus:=hb_dynCall( { "URLDownloadToFileA", nHandleDLL,HB_DYN_CALLCONV_STDCALL},0,"http://www1.caixa.gov.br/loterias/_arquivos/loterias/D_lotfac.zip","D_lotfac.zip",0,0)
   hb_LibFree(nHandleDLL)
RETURN Nil
►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)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usar uma DLL externa

Mensagem por JoséQuintas »

O fonte fica mais enxuto usando a função própria do Harbour

Código: Selecionar todos

UrlDownloadFile( "http://www1.caixa.gov.br/loterias/_arquivos/loterias/D_lotfac.zip", "D_lotfac.zip" )
...
FUNCTION mywin_UrlDownloadToFile( cUrl, cFileName )

   LOCAL nErrorCode, pCaller := 0, lpIndStatusCallBack := 0 // para indicador de progresso

   nErrorCode := CallDll( "URLDownloadToFileA", "urlmon.dll", pCaller, cURL, cFileName, 0, lpIndStatusCallBack )
   RETURN nErrorCode == 0
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/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

Quintas,

hb_libLoad é do harbour, se não me engano calldll só na versão 3.2
►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)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

Segundo o changelog da versão fork:

* contrib/xhb/xhb.hbp
* contrib/xhb/xhb.hbx
+ contrib/xhb/xhbdll.prg
+ added CallDll() compatibility function. Unfortunately it
collides with the name used in hbmisc lib, so use it with
care. [UNTESTED]
►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)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

CallDll na versão fork só funciona com hbmisc.
►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)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usar uma DLL externa

Mensagem por JoséQuintas »

O cuidado é por ter CallDll() em hbmisc.lib e xhb.lib, mas diferentes.

changelog:

Criação da CallDll32() no Harbour 3.2
2010-05-27 19:57 UTC+0200 Viktor Szakats (vszakats.net/harbour)
* contrib/hbmisc/Makefile
+ contrib/hbmisc/calldll.prg
+ Added CALLDLL compatibility API interface:
CALLDLL32(), HB_DYNACALL1(), STRPTR(), PTRSTR(), UNLOADALLDLL().
; Lightly tested, it's based on core .dll functions, so it may only
need easy tweaking. Notice that this API support all platforms,
not just 32-bit Windows.
The original library is found in MINIGUI f.e.
Mudança do nome de CallDll32() pra CallDll() já no Harbour 3.4
2013-12-26 13:25 UTC+0100 Viktor Szakáts (vszakats users.noreply.github.com)
* contrib/hbmisc/calldll.prg
* contrib/hbmisc/hbmisc.hbx
* contrib/hbmisc/tests/calldll.prg
+ renamed CallDll32() to CallDll() [INCOMPATIBLE]
; CallDll32() kept for compatibility under HB_LEGACY_LEVEL4
Adição de outra CallDll() pra compatibilidade xHarbour, que resultou em nome repetido
2014-09-17 21:50 UTC+0200 Viktor Szakats (vszakats users.noreply.github.com)
+ contrib/xhb/xhbdll.prg
+ added CallDll() compatibility function. Unfortunately it
collides with the name used in hbmisc lib, so use it with
care. [UNTESTED]
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/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

Quintas,

A modificação na versão Fork eu testei com xhb e hbmisc, com xhb não funcionou, com hbmisc funcionou.
►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)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usar uma DLL externa

Mensagem por JoséQuintas »

É porque são diferentes. Foi isso que o VSzakats alertou no changelog.
Só por curiosidade, a função de compatibilidade está em contrib\xhb\xhbdll.prg

Código: Selecionar todos

#include "hbdyn.ch"

/* NOTE: This compatibility function is clashing with a function
         using a similar name but different parameter list in hbmisc */
FUNCTION CallDll( pFunc, ... )
   RETURN iif( Empty( pFunc ),, hb_DynCall( { pFunc, HB_DYN_CALLCONV_STDCALL }, ... ) )
Essa foi criada apenas pra compatibilidade com xHarbour.

Acho que é a única função repetida que existe no Harbour, em bibliotecas diferentes.
Não sei se basta colocar a hbmisc.lib antes de xhb.lib pra evitar essa função diferente.

A intenção da biblioteca de compatibilidade é pra conversão inicial, não pra ser usada pra sempre, acho que por isso foi mantido o mesmo nome.
Mas é um negócio perigoso manter duas funções diferentes com nome igual.
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/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

Quintas,

Isso mesmo, testei agora hbmisc antes de xhb funcionou.
►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)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

O interessante neste caso é que não dá erro na compilação sobre nome de função duplicada.
►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)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Usar uma DLL externa

Mensagem por JoséQuintas »

Regra tradicional de linqueditor:
Não achou a função, busca nas LIBs indicadas, seguindo a ordem das LIBs.
E não junta a LIB inteira, somente as partes necessárias.

Por exemplo:
Um PRG pode conter várias funções, e ao compilar vira um objeto, e esse objeto vai pra LIB.
Um outro PRG tem várias funções e mais essa repetida do primeiro, vira um objeto, vai pra LIB.
Ao linqueditar, se usar função só de um, só aquele vai para o EXE e não dá duplicidade.
Se usar função dos dois, os dois vão para o EXE, e aí sim dá duplicidade.
Mas isso se o linqueditor acusar erro quando é duplicidade de LIB.

Interessante isso.
Tantos avanços, e continua valendo a regra de 30 anos atrás.
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/
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Usar uma DLL externa

Mensagem por asimoes »

Quintas e isso é perigoso, funções com o mesmo nome com funcionamento diferente, os resultados podem ser catastróficos, teriamos que olhar todos os fontes da lib para saber onde faz o certo/errado como no caso tbrowse lembra? método :setkey
►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)
Responder