Criar Dll (x)Harbour para utilização com Delphi/Lazarus

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

Moderador: Moderadores

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

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

Rochinha,

Bom dia,

Boas notícias!!!

Consegui gerar a dll exportável com MinGw.

Testei com rundll32 e um programa de teste feito em harbour.

Essa foi até mais fácil.

DllMinGw.prg -> DllMinGw.dll (o mesmo fonte utilizado para gerar a dll em msvc)

Código: Selecionar todos

**
* Fonte da DLL
**

#include "windows.ch"
#include "hwgui.ch"
#include "common.ch"
#include "guilib.ch"

PROCEDURE MyMethod
   hwg_MsgInfo("FUNÇÃO MyMethod com "+HB_Compiler())
RETURN 

FUNCTION Beepar()
RETURN Tone( 500 ) 

#pragma BEGINDUMP
  #include <windows.h>
  #include <hbvm.h>
  #include <hbapiitm.h>
  
  #define DllExport __declspec( dllexport )
  #define DllImport __declspec( dllimport )
  
  BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
  {
  HB_SYMBOL_UNUSED( hinstDLL );
  HB_SYMBOL_UNUSED( fdwReason );
  HB_SYMBOL_UNUSED( lpvReserved );
  switch( fdwReason )
  {
   case DLL_PROCESS_ATTACH:
    hb_vmInit( FALSE );
    break;
   case DLL_PROCESS_DETACH:
    hb_vmQuit();
    break;
  } 
  return TRUE;
  }
  // http://msdn.microsoft.com/pt-br/library/dt232c9t.aspx
  // __declspec(dllexport) void __cdecl Function1(void);
  // DllExport void __cdecl Function1(void);
  // OLESRV4.DEF
  // EXPORTS
  //  Beepar=_Beepar@0
  // A decoração de nome __stdcall prefixa o nome do símbolo com um sublinhado (_) e 
  // acrescenta o símbolo com um caractere da arroba (@) seguido pelo número de bytes 
  // na lista de argumentos (o espaço de pilha necessário). 
  // Como resultado, a função quando declarada como:
  // int __stdcall func (int a, double b)
  // é decorado como:
  // _func@12
  // A convenção de chamada do C (__cdecl) decora o nome como _func.
  // Para obter o nome decorado, use /MAP. O uso de __declspec(dllexport) faz o seguinte:
  // - Se a função for exportada com a convenção de chamada C (_cdecl), ela tira o sublinhado (_) principal quando o nome é exportado.
  // - Se a função que está sendo exportada não usa a convenção de chamada C (por exemplo, __stdcall), ela exporta o nome decorado.
  // Como não há nenhuma maneira de substituir onde a limpeza de pilha ocorre, você deve usar __stdcall. Para os nomes não 
  // decorados com __stdcall, você deve especificá-los usando aliases na seção de EXPORTAÇÕES do arquivo .def. 
  // Isso será mostrado a seguir para a seguinte declaração de função:
  //     int __stdcall MyFunc (int a, double b);
  //     void __stdcall InitCode (void);
  // No arquivo .DEF:
  //     EXPORTS
  //      MYFUNC=_MyFunc@12
  //      INITCODE=_InitCode@0
  // Substituir __declspec(dllexport) void __cdecl Beepar()
  // por void pascal __export Beepar()
  // __declspec(dllexport) void __cdecl Beepar() ** not work **
  //__declspec(dllexport) void __stdcall Beepar()
  //void pascal __export Beepar()
  //DllExport void pascal Beepar()
  DllExport void _cdecl  Beepar()
  { 
  hb_itemDoC( "Beepar", 0 );
  }
  
  DllExport void _cdecl  MyMethod()
  { 
  hb_itemDoC( "MyMethod", 0 );
  }
  
#pragma ENDDUMP
Bat para compilar:

Código: Selecionar todos

@echo off
set path=d:\hb32\bin
set HB_DBG_PATH=.\
set hb_compiler=mingw
hbmk2 dllmingw.hbp -rebuild
pause
Script de compilação: DllMinGw.hbp

Código: Selecionar todos

# ---------------------------------------------------------------------------------
# Script de constru‡Æo da lib HPROC
# ---------------------------------------------------------------------------------
# Autor     : Alexandre Simäes
# VersÆo    : 1.0
# Data      : 09/04/2012
# Harbour   : Harbour 3.1.0dev (Rev. 17207) Copyright (c) 1999-2012,
#             http://harbour-project.org/
# Compilador: MinGW GNU C 4.6.1 (32-bit)
# ---------------------------------------------------------------------------------
# Nome da Lib
# ---------------------------------------------------------------------------------
-oDllMinGw
-lhwgui
-lprocmisc
-lhbgt
-lgtwvg
-lgtwvt
-lhbct
-lhbwin
-lhbnf
-lxhb
-lhbtip
-lhbblink
hbct.hbc
-gtgui
# ---------------------------------------------------------------------------------
# Caminhos dos Includes
# ---------------------------------------------------------------------------------
#-incpath=d:\hb32\hwgui\include;
#-Ld:\hb32\hwgui\lib;
-incpath=d:\hb32\hwgui\include;
-Ld:\hb32\hwgui\lib;
# ---------------------------------------------------------------------------------
# Outros Parƒmetros
# ---------------------------------------------------------------------------------
-workdir=.\OBJMINGW
-head=full
-n
-warn=no
-inc
-dHARBOUR 
-b
# ---------------------------------------------------------------------------------
# Prg(s) e Rc(s)
# ---------------------------------------------------------------------------------
-hbdynvm
DllMinGw.prg
Programa para testar:

Código: Selecionar todos

/*
 * Harbour Project source code:
 *    Dynamic library call demonstration. (on Windows)
 *
 * Copyright 2008 Viktor Szakats (vszakats.net/harbour)
 * www - http://harbour-project.org
 *
 */

#include "simpleio.ch"
#include "wvtwin.ch"
#include "hbcompat.ch"
#include "hbgtinfo.ch"
#include "hbgtwvg.ch"
#include "wvgparts.ch"
#include "dbinfo.ch"
#include "fileio.ch"
#include "hbdyn.ch"
#include "common.ch"
#include "set.ch"
#include "inkey.ch"

PROCEDURE Main()

   hLib := hb_libLoad( "DllMinGW.dll" )
   
   //altd()
   
   IF ! Empty( hLib )
      n:=hb_DynCall( { "MyMethod", hLib, HB_DYN_CALLCONV_STDCALL })
      hb_libFree( hLib )
   ENDIF

   RETURN

INIT FUNCTION AppSetup()
  
  REQUEST HB_LANG_PT
  REQUEST HB_CODEPAGE_PT850
  HB_LANGSELECT("PT")
  HB_CDPSELECT( "PT850" ) //pt850
  
  REQUEST DBFCDX
  
  RddSetDefault("DBFCDX")
  
  SETMODE(25,80)
 
  SetColor("W+/B")
  
  CLS
 
  SetColor("W+/B")
  
  IniciaJanela()
 
  //Inkey(4) 

RETURN Nil 
 

FUNCTION IniciaJanela(nLi,nCi,nLf,nCf)
 
LOCAL oCrt

PUBLIC nJanelaAplicacao, oDlgHabla

   HB_Default(@nLi,0)
   HB_Default(@nCi,0)
   HB_Default(@nLf,MaxRow())
   HB_Default(@nCf,MaxCol())
  
   cTituloJanela:="Teste com DLL"
 
   HB_gtInfo(HB_GTI_FONTNAME, "Lucida Console")
   HB_gtInfo(HB_GTI_WINTITLE, cTituloJanela)

   //HB_gtInfo(HB_GTI_ICONRES, "IPRINTER2" ) 
   HB_gtInfo(HB_GTI_CLOSABLE, .F. )
   HB_gtInfo(HB_GTI_ISGRAPHIC, .T. )
   HB_gtInfo(HB_GTI_STDERRCON, .T. )
   HB_gtInfo(HB_GTI_COMPATBUFFER, .T. ) 
   HB_gtInfo(HB_GTI_SPEC, HB_GTS_WNDSTATE, HB_GTS_WS_MAXIMIZED )
   HB_gtInfo(HB_GTI_SPEC, HB_GTS_SHOWWINDOW, SW_NORMAL )
   
   nJanelaAplicacao:=hwg_FindWindow(,HB_gtInfo(HB_GTI_WINTITLE))
      
RETURN Nil
 
FUNCTION HB_GTSYS()
   REQUEST HB_GT_WVG_DEFAULT
   REQUEST HB_GT_WVT
   REQUEST HB_GT_WGU
   REQUEST HB_GT_WVG
RETURN Nil 
Bat para compilar o programa de teste dynwin.prg

Código: Selecionar todos

@echo off
set path=d:\hbmsvcfork32\bin;d:\hbmsvcfork32\comp\msvc\bin
set hb_compiler=msvc
set include=d:\hbmsvcfork32\comp\msvc\include
set lib=d:\hbmsvcfork32\comp\msvc\lib
set HB_DBG_PATH=.\
hbmk2 dynwin.hbp -rebuild
pause
:)Pos
►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
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por rochinha »

:D

Parabéns, a UNIÃO faz açucar, PC TOLEDO a força! :))

Este trabalho vai servir a muita gente, pois com os testes que você fez complementaram em muito e sinceramente foi 80% do trabalho.

Agora a base está criada, bastará vermos os resultados que poderão surgir. Como as DLLs são praticamente aplicativos executáveis, pode-se moldar uma estrutura de aplicativos de deferentes produtores para compor um conjunto.

Estariamos fazendo nascer a componentização em Harbour.

O único impecilho num uso de vários componentes em um conjunto seria o VISUAL.

Eu vejo que existe uma leve diferença no visual dos controles das aplicações feitas mesmo que no Windows, pois a API está em seu modo cru, e cada produtor modela a mesma dando suas características, conferindo a sua assinatura.

Então mãos a obra. :xau
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

Rochinha,

Pra fechar o leque de opções para gerar a dll com borland c++ usando o hbmk2/script
Gerando o mesmo exemplo inicial da MiniGui funções PlayDraw e Main com passagem de parâmetros:

bat para gerar a dll

Código: Selecionar todos

@echo off
SET PATH=%PATH%;D:\BORLAND\BCC58\BIN;D:\MINIGUI\HARBOUR\BIN
SET HB_COMPILER=bcc
HBMK2 DLLBCC.HBP -jobs=%NUMBER_OF_PROCESSORS% -rebuild
pause
Fonte DllBcc.prg -> DllBcc.dll

Código: Selecionar todos

/*

   PlayDraw.prg

   Needless affairs !

   Some 2 dimension drawing efforts on a totally 3 dimensioned world !

   Experimentations on some HMG's DRAW commands.

   Copyrigth : Everybody can play with any way like :)

   Author : Bicahi Esgici

   History :
            July 2012 : First release

*/

#include <hmg.ch>

#define  n2Pi ( 44 / 7 )
#define  nStylCount  4

Static nSkipLevel := 0
Static aColorS    := { YELLOW, RED, WHITE, BLUE, FUCHSIA, GREEN,  PURPLE, GRAY, PINK, BROWN, ORANGE }
Static lFrmRSized := .F.  // Form ReSized

PROCEDURE Main(cTitulo, dData)
  
  hb_Default(@cTitulo,"DBF Header Infomação") 
  hb_Default(@dData,Date()) 

  MsgInfo(cTitulo+" "+hb_dtoc(dData,"DD/MM/YYYY"))

RETURN

PROCEDURE PlayDraw()

   DEFINE WINDOW frmPlayDraw ;
      AT 0, 0 ;
      WIDTH  600 ;
      HEIGHT 600 ;
      TITLE "Playing by Drawing" ;
      MAIN ;
      BACKCOLOR { 0, 0, 0 }  ;
      ON INIT GoDraw() ;
      ON SIZE ( lFrmRSized := .T. ) ;
      ON MAXIMIZE ( lFrmRSized := .T. )

      ON KEY ESCAPE    ACTION frmPlayDraw.Release

      ON KEY HOME      ACTION ( nSkipLevel := 4 )   // Go BOF   
      ON KEY NEXT      ACTION ( nSkipLevel := 3 )   // Next Style
      ON KEY DOWN      ACTION ( nSkipLevel := 2 )   // Next Color
      ON KEY RIGHT     ACTION ( nSkipLevel := 1 )   // Next Shape

      @ 20, 20 BUTTON btnHelp CAPTION "?" BOLD WIDTH 20 HEIGHT 20 ;
               TOOLTIP "Keys" ;
               ACTION MsgInfo( "HOME : Restart"    + CRLF +;
                               "NEXT : Next Style" + CRLF +;
                               "DOWN : Next Color" + CRLF +;
                               "RIGHT : Next Shape" )

   END WINDOW // frmPlayDraw

   frmPlayDraw.Center
   frmPlayDraw.Activate

RETURN // Main()

*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._

PROCEDURE GoDraw()                       // Drawing lines by predefined styles

   LOCAL nStyleNum    := 1,;
         nFormWidth,;
         nFormHeigth,;
         nFormCenterX,;
         nFormCenterY,;
         nHorRadius,;
         nVerRadius,;
         nLinePenW

   LOCAL aPCCounts := { ;                       // Point & Corner Counts per Style
                        { 12, 48, 48, 32 },;       // Point Counts
                        { 12, 48,  3,  1 } }       // Corner Counts

   LOCAL nPCount,;
         nCCount,;
         nRatio

   LOCAL nHDecrement,;
         nVDecrement,;
         nZStep       := 0

   LOCAL aParams

   LOCAL nFactor,;
         nLineBeg,;
         nLineEnd

   LOCAL nFactBeg,;
         nFactEnd,;      
         nFactStp,;         
         nLBegBeg,;
         nLBegEnd,;
         nLBegStp,;
         nLCrmBeg,;
         nLCrmEnd,;
         nLCrmStp

   LOCAL a1Color, aColorNo, nDelay, nCornCremnt, nHRadius, nVRadius,;
         nLineBegY, nLineBegX, nLineEndY, nLineEndX, nBaseCrm

   WHILE .T.
   
      nPCount     := aPCCounts[ 1, nStyleNum ]
      nCCount     := aPCCounts[ 2, nStyleNum ] 
      nRatio      := nPCOunt / nCCOunt 
      aParams     := { ;
                        { ;                                       // Style 1
                          { 1,        2,       .1 },;             // nFactor
                          { 1,        nPCount,  1 },;             // nLineBeg
                          { 1,        nPCount,  1 };              // nCornCremnt
                        },;                                          // EOF Style 1 
                        { ;                                       // Style 2
                          { 0,        3,       .5 },;             // nFactor
                          { 1,        nPCount,  1 },;             // nLineBeg
                          { 0,        nPCount,  nPCOunt / 4 };    // nCornCremnt
                        },;                                          // EOF Style 2 
                        { ;                                       // Style 3
                          { 0,        8,        1 },;             // nFactor
                          { 1,        nRatio,   1 },;             // nLineBeg
                          { nRatio,   nPCount,  nRatio };         // nCornCremnt
                        },;                                          // EOF Style 3
                        { ;                                       // Style 4
                          { 2,        8,        1 },;             // nFactor
                          { 1,        nPCount,  1 },;             // nLineBeg
                          { nZStep-1, nPCount,  nZStep };         // nCornCremnt
                        };                                           // EOF Style 4
                     }                                            // EOF aParams
                          
      nFactBeg := aParams[ nStyleNum, 1, 1 ]
      nFactEnd := aParams[ nStyleNum, 1, 2 ]
      nFactStp := aParams[ nStyleNum, 1, 3 ]
      nLBegBeg := aParams[ nStyleNum, 2, 1 ]
      nLBegEnd := aParams[ nStyleNum, 2, 2 ]
      nLBegStp := aParams[ nStyleNum, 2, 3 ]
      nLCrmBeg := aParams[ nStyleNum, 3, 1 ]
      nLCrmEnd := aParams[ nStyleNum, 3, 2 ]
      nLCrmStp := aParams[ nStyleNum, 3, 3 ]
      
      WHILE .T.     
      
         ERASE WINDOW frmPlayDraw
         
         nFormWidth   := frmPlayDraw.WIDTH
         nFormHeigth  := frmPlayDraw.HEIGHT - 20
         nFormCenterX := nFormWidth / 2
         nFormCenterY := nFormHeigth / 2
         nHorRadius   := nFormCenterX * .75
         nVerRadius   := nFormCenterY * .75
         nLinePenW    := 1
         
         nHDecrement  := nHorRadius / nPCOunt
         nVDecrement  := nVerRadius / nPCOunt
      
         FOR aColorNo := 1 TO LEN( aColorS )
         
            a1Color := aColorS[ aColorNo ]
               
            IF nStyleNum = 1               
               nHRadius := nHorRadius
               nVRadius := nVerRadius
            ENDIF nStyleNum = 1               
         
            FOR nFactor := nFactBeg TO nFactEnd STEP nFactStp     
            
               ERASE WINDOW frmPlayDraw
               
               IF nStyleNum = 1
               
                  IF nFactor < nFactBeg + ( nFactEnd - nFactBeg ) / 2 
                     nHRadius := nHorRadius / nFactor
                  ELSE
                     nVRadius := nVerRadius / ( nFactBeg + ( nFactEnd - nFactor ) )
                     nHRadius := nHorRadius
                  ENDIF nFactor < 6
                  
               ENDIF nStyleNum = 1
               
               IF nStyleNum = 4               
                  nHRadius := nHorRadius
                  nVRadius := nVerRadius
               
                  nLineBegX := nHRadius * COS( n2Pi / nPCOunt ) + nFormCenterX
                  nLineBegY := nVRadius * SIN( n2Pi / nPCOunt ) + nFormCenterY
      
                  nZStep    := ( nPCOunt + 1 ) / nFactor
                  
                  nLCrmBeg  := nZStep - 1
                  nLCrmStp  := nZStep
                  
               ENDIF nStyleNum = 4               
               
               FOR nLineBeg := nLBegBeg TO nLBegEnd STEP nLBegstp
               
                  IF nStyleNum > 1 .AND. nStyleNum < 4
                     nVRadius := nVerRadius - nFactor * nLineBeg
                     nHRadius := nHorRadius - nFactor * nLineBeg
                  ENDIF nStyleNum > 1 .AND. nStyleNum < 4
               
                  IF nStyleNum < 3 .OR. nLineBeg < 2
                     nLineBegY := nVRadius * COS( n2Pi / nPCOunt * nLineBeg ) + nFormCenterY
                     nLineBegX := nHRadius * SIN( n2Pi / nPCOunt * nLineBeg ) + nFormCenterX
                  ENDIF
                  
                  IF nStyleNum = 1    
                     nLCrmBeg := nLineBeg
                  ENDIF nStyleNum = 1               
                  
                  IF nStyleNum = 4               
                     nHRadius := nHRadius - nHDecrement
                     nVRadius := nVRadius - nVDecrement
                  ENDIF nStyleNum = 4               
      
                  FOR nCornCremnt := nLCrmBeg TO nLCrmEnd STEP nLCrmStp
                  
                     IF nStyleNum = 1               
                        nBaseCrm := 0                         
                     ELSE
                        nBaseCrm := nLineBeg
                     ENDIF   
                     
                     nLineEnd := nBaseCrm + nCornCremnt
                     
                     IF nStyleNum < 4               
                        IF nLineEnd > nPCOunt
                           nLineEnd := nLineEnd - nCornCremnt
                        ENDIF
                     ENDIF nStyleNum < 4               
                     
                     IF nStyleNum > 1 .AND. nStyleNum < 4              
                        nVRadius := nVerRadius - nFactor * nLineEnd
                        nHRadius := nHorRadius - nFactor * nLineEnd
                     ENDIF nStyleNum > 1 .AND. nStyleNum < 4              
         
                     nLineEndY := nFormCenterY + ( nVRadius * COS( n2Pi / nPCount * nLineEnd ) )
                     nLineEndX := nFormCenterX + ( nHRadius * SIN( n2Pi / nPCount * nLineEnd ) )
                           
                     DRAW LINE IN WINDOW frmPlayDraw  AT nLineBegY, nLineBegX ;
                                                      TO nLineEndY, nLineEndX ;
                                                      PENCOLOR a1Color ;
                                                      PENWIDTH nLinePenW
                                                      
                     IF nStyleNum > 2               
                        nLineBegY := nLineEndY
                        nLineBegX := nLineEndX
                     ENDIF nStyleNum > 2               
                     
                     nDelay := SECONDS()
                           
                     WHILE ( SECONDS() - nDelay ) < .01
                        DO EVENTS
                     ENDDO
                     
                     IF lFrmRSized
                        EXIT
                     ENDIF
   
                     IF nSkipLevel > 0
                        EXIT
                     ENDIF
                     
                  NEXT nCornCremnt
                  
                  IF lFrmRSized
                     EXIT
                  ENDIF
                  
                  IF nSkipLevel > 0
                     --nSkipLevel
                     EXIT
                  ENDIF
                        
               NEXT nLineBeg
   
               IF lFrmRSized
                  EXIT
               ENDIF
               
               IF nSkipLevel > 0
                  --nSkipLevel
                  EXIT
               ENDIF

            NEXT nFactor
            
            IF nSkipLevel > 0
               --nSkipLevel
               EXIT
            ENDIF
            
            IF lFrmRSized
               EXIT
            ENDIF
                  
         NEXT a1Color   
         
         IF lFrmRSized
            lFrmRSized := .F. 
            LOOP
         ENDIF
         
         IF nSkipLevel > 0
            nSkipLevel := 0
            nStyleNum  := 0
         ENDIF
         
         EXIT
         
      ENDDO
      
      ++nStyleNum
      
      IF nStyleNum > nStylCount
         nStyleNum := 1
      ENDIF
      
   ENDDO
   
RETURN // GoDraw()   

*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._

#pragma BEGINDUMP
  #include <windows.h>
  #include <hbvm.h>
  #include <hbapiitm.h>
  
  #define DllExport __declspec( dllexport )
  #define DllImport __declspec( dllimport )
  
  BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
  {
  HB_SYMBOL_UNUSED( hinstDLL );
  HB_SYMBOL_UNUSED( fdwReason );
  HB_SYMBOL_UNUSED( lpvReserved );
  switch( fdwReason )
  {
   case DLL_PROCESS_ATTACH:
    hb_vmInit( FALSE );
    break;
   case DLL_PROCESS_DETACH:
    hb_vmQuit();
    break;
  } 
  return TRUE;
  }
  // http://msdn.microsoft.com/pt-br/library/dt232c9t.aspx
  // __declspec(dllexport) void __cdecl Function1(void);
  // DllExport void __cdecl Function1(void);
  // OLESRV4.DEF
  // EXPORTS
  //  Beepar=_Beepar@0
  // A decoração de nome __stdcall prefixa o nome do símbolo com um sublinhado (_) e 
  // acrescenta o símbolo com um caractere da arroba (@) seguido pelo número de bytes 
  // na lista de argumentos (o espaço de pilha necessário). 
  // Como resultado, a função quando declarada como:
  // int __stdcall func (int a, double b)
  // é decorado como:
  // _func@12
  // A convenção de chamada do C (__cdecl) decora o nome como _func.
  // Para obter o nome decorado, use /MAP. O uso de __declspec(dllexport) faz o seguinte:
  // - Se a função for exportada com a convenção de chamada C (_cdecl), ela tira o sublinhado (_) principal quando o nome é exportado.
  // - Se a função que está sendo exportada não usa a convenção de chamada C (por exemplo, __stdcall), ela exporta o nome decorado.
  // Como não há nenhuma maneira de substituir onde a limpeza de pilha ocorre, você deve usar __stdcall. Para os nomes não 
  // decorados com __stdcall, você deve especificá-los usando aliases na seção de EXPORTAÇÕES do arquivo .def. 
  // Isso será mostrado a seguir para a seguinte declaração de função:
  //     int __stdcall MyFunc (int a, double b);
  //     void __stdcall InitCode (void);
  // No arquivo .DEF:
  //     EXPORTS
  //      MYFUNC=_MyFunc@12
  //      INITCODE=_InitCode@0
  // Substituir __declspec(dllexport) void __cdecl Beepar()
  // por void pascal __export Beepar()
  // __declspec(dllexport) void __cdecl Beepar() ** not work **
  //__declspec(dllexport) void __stdcall Beepar()
  //void pascal __export Beepar()
  //DllExport void pascal Beepar()
  //DllExport void __cdecl  PlayDraw()

  DllExport void pascal PlayDraw()
  { 
     hb_itemDoC( "PlayDraw", 0 );
  }
  
  void pascal __export HBDLLENTRY2( char * cProcName, PHB_ITEM pParam1, PHB_ITEM pParam2)
  {
     hb_itemDoC( cProcName, 2, pParam1, pParam2);
  }
    
#pragma ENDDUMP
BccDll.hbp -> script de compilação

Código: Selecionar todos

# ---------------------------
# Nome do Executável/Dll
# ---------------------------
-oDllBcc
# ---------------------------
# Bibliotecas
# xhb deve ser depois de hbole
# ---------------------------
-ltsbrowse
-lpropgrid
-lminigui
-lminiprint
-lhbprinter 
-lgtgui
-lhbct
-lhbnf
-lhbwin
-lhbole
-lxhb
-lhbhpdf
-llibhpdf
-lhbzebra
-lhbnetio
-lpng
-lhbmemio
# ---------------------------
# Caminho dos Includes
# ---------------------------

-incpath=d:\minigui\harbour\include;
-incpath=d:\minigui\include;

# ---------------------------
# Caminho das Libs da MiniGui
# ---------------------------

-Ld:\minigui\lib

# ---------------------------
# Outros Parâmetros
# ---------------------------
-workdir=.\OBJDLL\
-gtgui
-head=full
-n
-dVERSAO_DE_TESTE1
-dVERSAO_DE_TESTE2
-warn=no
-inc
-hbdynvm
# ---------------------------
# Prg(s) e Rc(s)
# ---------------------------
DllBcc.prg
d:\minigui\resources\miniprint.rc
d:\minigui\resources\minigui.rc
d:\minigui\resources\hbprinter.rc
# ---------------------------
# Fim
# ---------------------------
Dynwin.prg -> Para testar a dll dllbcc.dll

Código: Selecionar todos

/*
 * Harbour Project source code:
 *    Dynamic library call demonstration. (on Windows)
 *
 * Copyright 2008 Viktor Szakats (vszakats.net/harbour)
 * www - http://harbour-project.org
 *
 */

#include "simpleio.ch"
#include "wvtwin.ch"
#include "hbcompat.ch"
#include "hbgtinfo.ch"
#include "hbgtwvg.ch"
#include "wvgparts.ch"
#include "dbinfo.ch"
#include "fileio.ch"
#include "hbdyn.ch"
#include "common.ch"
#include "set.ch"
#include "inkey.ch"

PROCEDURE Main()

   LOCAL hLib
   LOCAL cData

   hItem1:=itemNew("Nova Janela")
   hItem2:=itemNew( Date() + 1 )

   hLib := hb_libLoad( "dllbcc.dll" )
   
   IF ! Empty( hLib )
      hb_DynCall( { "HBDLLENTRY2", hLib, hb_bitOr( HB_DYN_CTYPE_CHAR_PTR , HB_DYN_CALLCONV_STDCALL )  },"Main", hItem1, hItem2 )
   ENDIF
   
   ItemRelease( hItem1 )
   ItemRelease( hItem2 )
   
   IF ! Empty( hLib )
      hb_DynCall( { "PlayDraw", hLib, HB_DYN_CTYPE_CHAR_PTR } )
      hb_libFree( hLib )
   ENDIF

   RETURN

INIT FUNCTION AppSetup()
  
  REQUEST HB_LANG_PT
  REQUEST HB_CODEPAGE_PT850
  HB_LANGSELECT("PT")
  HB_CDPSELECT( "PT850" ) //pt850
  
  REQUEST DBFCDX
  
  RddSetDefault("DBFCDX")
  
  SETMODE(25,80)
 
  SetColor("W+/B")
  
  CLS
 
  SetColor("W+/B")
  
  IniciaJanela()
 

RETURN Nil 
 

FUNCTION IniciaJanela(nLi,nCi,nLf,nCf)
 
LOCAL oCrt

PUBLIC nJanelaAplicacao, oDlgHabla

   HB_Default(@nLi,0)
   HB_Default(@nCi,0)
   HB_Default(@nLf,MaxRow())
   HB_Default(@nCf,MaxCol())
  
   cTituloJanela:="Teste com DLL"
 
   HB_gtInfo(HB_GTI_FONTNAME, "Lucida Console")
   HB_gtInfo(HB_GTI_WINTITLE, cTituloJanela)
   //HB_gtInfo(HB_GTI_ICONFILE, "P:\GERAL\HARBOUR\HARB_WIN.ICO" )
   HB_gtInfo(HB_GTI_ICONRES, "IPRINTER2" ) 
   HB_gtInfo(HB_GTI_CLOSABLE, .F. )
   HB_gtInfo(HB_GTI_ISGRAPHIC, .T. )
   HB_gtInfo(HB_GTI_STDERRCON, .T. )
   HB_gtInfo(HB_GTI_COMPATBUFFER, .T. ) 
   HB_gtInfo(HB_GTI_SPEC, HB_GTS_WNDSTATE, HB_GTS_WS_MAXIMIZED )
   HB_gtInfo(HB_GTI_SPEC, HB_GTS_SHOWWINDOW, SW_NORMAL )
   
   nJanelaAplicacao:=hwg_FindWindow(,HB_gtInfo(HB_GTI_WINTITLE))
      
RETURN Nil
 
FUNCTION HB_GTSYS()
   REQUEST HB_GT_WVG_DEFAULT
   REQUEST HB_GT_WVT
   REQUEST HB_GT_WGU
   REQUEST HB_GT_WVG
RETURN Nil 

#pragma BEGINDUMP

#include <hbapi.h>
#include <hbapiitm.h>

HB_FUNC( ITEMNEW )
{
   hb_retnl( ( unsigned long ) hb_itemNew( hb_param( 1, HB_IT_ANY ) ) );
}

HB_FUNC( ITEMRELEASE )
{
   hb_retl( hb_itemRelease( ( PHB_ITEM ) hb_parnl( 1 ) ) );
}

#pragma ENDDUMP    
Bat para compilar dynwin.prg

Código: Selecionar todos

@echo off
set path=d:\hb32\bin
SET HB_COMPILER=mingw
set HB_DBG_PATH=.\
hbmk2 dynwin.hbp -rebuild
pause
►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
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por rochinha »

:D

Amiguinho, agora está servindo a todos os gostos. Nota 1000.

:-Y
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

Olá Rochinha,

Estou tentando passar uma variável por referencia para a dll, como fazemos no clipper:
Não estou conseguindo exemplos, baseado nos exemplos que postei, tem como?

Código: Selecionar todos

cVar:=""

Funcao(@cVar)

? cVar

FUNCTION Funcao(cVar)
   cVar:="Outro valor"
RETURN cVar
►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

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

No programa que chama a dll
Passando a variável por referência cText1, não está trocando o valor, o que será?

Código: Selecionar todos

     hLib := hb_libLoad( "dllbcc.dll" )
     cText1:="" 
     x:=hb_DynCall( { "HBDLLSTRING5", hLib, hb_bitOr( HB_DYN_CTYPE_CHAR_PTR , HB_DYN_CALLCONV_STDCALL )  },"Test5", @cText1, "Top of Box", "Item 3" )
     MsgInfo(cText1)
     hb_libFree( hLib )
A DLL

Código: Selecionar todos

FUNCTION Test5( cText1, cText2, cText3 )
local cr:=chr(13)

   cText1:=cText1+"This is being added on in the DLL."
   cText1:=cText1+"     So Far so good."

   MsgInfo( cText1, cText2 )

   MsgInfo( cText3, "AAA" )

RETURN (cText1)

#pragma BEGINDUMP
  #include <windows.h>
  #include <hbvm.h>
  #include <hbapiitm.h>
  
  #define DllExport __declspec( dllexport )
  #define DllImport __declspec( dllimport )
  
  BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
  {
  HB_SYMBOL_UNUSED( hinstDLL );
  HB_SYMBOL_UNUSED( fdwReason );
  HB_SYMBOL_UNUSED( lpvReserved );
  switch( fdwReason )
  {
   case DLL_PROCESS_ATTACH:
    hb_vmInit( FALSE );
    break;
   case DLL_PROCESS_DETACH:
    hb_vmQuit();
    break;
  } 
  return TRUE;
  }

  DllExport char * PASCAL HBDLLSTRING5( char * cProcName, char * cText1, char * cText2, char * cText3  )
  {
   PHB_ITEM pResult;  
   PHB_ITEM pItem1 = hb_itemPutC( NULL, cText1 );
   PHB_ITEM pItem2 = hb_itemPutC( NULL, cText2 );
   PHB_ITEM pItem3 = hb_itemPutC( NULL, cText3 );
   MessageBox( 0, "Point  in hbdllstring5", "1", 0 );
   pResult = hb_itemDoC( cProcName, 3,  pItem1, pItem2, pItem3, 0 );
   hb_itemRelease( pItem1 );
   hb_itemRelease( pItem2 );
   hb_itemRelease( pItem3 );
   return hb_itemGetC( pResult );
  }
    
#pragma ENDDUMP

►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
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por rochinha »

Amiguinho,

Vou fazer uns testes também e logo darei retorno.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por rochinha »

Amiguinho,

Modifique a linha

Código: Selecionar todos

...
DllExport char * PASCAL HBDLLSTRING5( char *cProcName, char *cText1, char *cText2, char *cText3  )
...
Para:

Código: Selecionar todos

...
DllExport char * PASCAL HBDLLSTRING5( char *cProcName, char *cText1, char &cText2, char *cText3  )
...
Onde o " & " em C++ define modo de assinalação de variáveis por referência.

Como vê, tamém VÔ aprendeno.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

Olá Rochinha,

Fiz o indicado e na compilação dá esse erro:


Harbour 3.2.0dev (r1409051124)
Copyright (c) 1999-2014, http://harbour-project.org/
Compiling 'DllBcc.prg'...
Lines 21984, Functions/Procedures 4
Generating C source output to 'DllBcc.c'... Done.
Borland C++ 5.82 for Win32 Copyright (c) 1993, 2005 Borland
DllBcc.c:
Error E2293 DllBcc.prg 435: ) expected
►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

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

Essa tá difícil de resolver:

O máximo que eu consegui foi retornar valor.

Uma função na dll Teste()

DllExport pascal int Teste(int a)
{
a ++;
return a;
}

A chamada:

n:=0
x:=hb_DynCall( { "Teste", hLib, HB_DYN_CTYPE_INT} ,n) //funciona
x retorna 1 n = 0

x:=hb_DynCall( { "Teste", hLib, HB_DYN_CTYPE_INT} ,@n) //não funciona
x retorna um ponteiro 3764029 e n = 0
►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
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por rochinha »

Amiguinho,

Depende da disposição do C que estivermos usando para assinalar os ponteiros, exemplo:

Quando definimos um ponteiro estamos guardando um local da memoria só para manipular esta variável.

Usando C:

Código: Selecionar todos

DllExport pascal int Teste(int *a)
{ 
*a ++;
return (0);
}
Usando C++

Código: Selecionar todos

DllExport pascal int Teste(int *a)
{ 
&a ++;
return (0);
}
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

Rochinha resolvi uma parte do problema:
Para não dá erro para o compilador, criei um arquivo dllbcc.cpp, compilou com êxito.

A função ficou com o nome @Teste$qri
Imagem

Imagem

Criei um arquivo .def (dllbcc.def) com:

EXPORTS
Teste=@Teste$qri

Na imagem acima o nome da função ficou certo Teste

Inclui esse arquivo no dllbcc.hbp

Para testar:

n:=2

x:=hb_DynCall( { "Teste", hLib, HB_DYN_CTYPE_INT} ,@n) //funciona

n retornou 3, funcionou a passagem por referência.

dllbcc.cpp

Código: Selecionar todos

  #include <windows.h>
  #include <hbvm.h>
  #include <hbapiitm.h>
  #include <hbapi.h>
  
  #define DllExport __declspec( dllexport )
  #define DllImport __declspec( dllimport )
  
  #include <stdio.h> 
  #include <ctype.h>
  
  #include <stdlib.h>
  
  BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
  {
  HB_SYMBOL_UNUSED( hinstDLL );
  HB_SYMBOL_UNUSED( fdwReason );
  HB_SYMBOL_UNUSED( lpvReserved );
  switch( fdwReason )
  {
   case DLL_PROCESS_ATTACH:
    hb_vmInit( FALSE );
    break;
   case DLL_PROCESS_DETACH:
    hb_vmQuit();
    break;
  } 
  return TRUE;
  }
  
  DllExport _cdecl int Teste( int &a)
  {
     a ++ ;
     return a;
  }
Agora estou tentando com esta função:
Ainda não deu certo.
Está dando esse erro no retorno da função:

Error E2034 Rotinas.cpp 74: Cannot convert 'char *' to 'char' in function HBDLLSTRING5(char *,char *
&,char *,char *)

Código: Selecionar todos

 DllExport _cdecl char HBDLLSTRING5( char * cProcName, char * &cText1, char * cText2, char * cText3  )
   {
   
   PHB_ITEM pResult;  
   PHB_ITEM pItem1 = hb_itemPutC( NULL, cText1 );
   PHB_ITEM pItem2 = hb_itemPutC( NULL, cText2 );
   PHB_ITEM pItem3 = hb_itemPutC( NULL, cText3 );

   //MessageBox( 0, cteste, "1", 0 );
   pResult = hb_itemDoC( cProcName, 3, pItem1, pItem2, pItem3, 0 );
   
   hb_itemRelease( pItem1 );
   hb_itemRelease( pItem2 );
   hb_itemRelease( pItem3 );
   
   return hb_itemGetC( pResult );
  }
►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
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por rochinha »

Amiguinho,

Voce entrou fundo no negócio heim?!

O compilador C que voce está usando adota C puro ou C++?

No momento da execução, uma variável que tenha sido nomeada como pointer, ou seja, definida com * e nome da variável, reservará um local na memória fisica para seu uso.

Em C++ é possível definir diretamente nos parâmetros que uma variável será de referência, usando o operador &. Quando definimos uma variável como referência e apontamos para ela não estamos apontando para o seu conteúdo e sim para o endereço de memória onde se encontra o seu valor.

Em:

Código: Selecionar todos

DllExport _cdecl char HBDLLSTRING5( char * cProcName, char * &cText1, char * cText2, char * cText3  )
Onde está char * &cText1 deixe char & cText1 ou char &cText1.

* é o operador que define nosso pointer, o conteúdo do nosso endereço de memória.
& é o operador que define o nosso ponto de referencia, um alvo.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por asimoes »

Rochinha,

Dá erro quando usa: char & cText1

Error E2034 Rotinas.cpp 58: Cannot convert 'int' to 'const char *' in function HBDLLSTRING5(char *,c
har &,char *,char *)
Error E2342 Rotinas.cpp 58: Type mismatch in parameter 'szText' (wanted 'const char *', got 'char')
in function HBDLLSTRING5(char *,char &,char *,char *)
►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
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Criar Dll (x)Harbour para utilização com Delphi/Lazarus

Mensagem por rochinha »

Amiguinho,

Deixe a seguinte linha assim:

Código: Selecionar todos

DllExport _cdecl char HBDLLSTRING5( char * cProcName, char &cText1, char &cText2, char &cText3  )
Ainda preciso buscar mais informações, mas PHB_ITEM já estaria definindo os parâmetros como ponteiro. Não encontrei ainda uma explicação para tal, já que isto é coisa do Harbour e não do C++.

Como nas linhas:

Código: Selecionar todos

           PHB_ITEM pItem1 = hb_itemPutC( NULL, cText1 );
           PHB_ITEM pItem2 = hb_itemPutC( NULL, cText2 );
           PHB_ITEM pItem3 = hb_itemPutC( NULL, cText3 );
Mas consultado sobre estas funções do Harbour encontrei hb_ItemPutCptr() que deve trabalhar com ponteiros enquanto hb_ItemPutC() não.

Talvez estas linhas ficassem melhor se fossem simplificadas:

Código: Selecionar todos

           char pItem1 = cText1 ;
           char pItem2 = cText2 ;
           char pItem3 = cText3 ;
Então

Código: Selecionar todos

DllExport _cdecl char HBDLLSTRING5( char * cProcName, char &cText1, char &cText2, char &cText3  )
	   {
	   PHB_ITEM pResult; 
           char pItem1 = cText1 ;
           char pItem2 = cText2 ;
           char pItem3 = cText3 ;

	   pResult = hb_itemDoC( cProcName, 3, pItem1, pItem2, pItem3, 0 );

	   hb_itemRelease( pItem1 );
	   hb_itemRelease( pItem2 );
	   hb_itemRelease( pItem3 );
	    
	   return hb_itemGetC( pResult );
	  }
Ou:

Código: Selecionar todos

DllExport _cdecl char HBDLLSTRING5( char * cProcName, char &cText1, char &cText2, char &cText3  )
	   {
	   PHB_ITEM pResult; 

	   pResult = hb_itemDoC( cProcName, 3, cText1, cText2, cText3, 0 );

	   hb_itemRelease( pItem1 );
	   hb_itemRelease( pItem2 );
	   hb_itemRelease( pItem3 );
	    
	   return hb_itemGetC( pResult );
	  }
Analise e confira.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Responder