How to call function from .dll library?

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: How to call function from .dll library?

Post by jparada »

Hi Krzysztof,
I am very grateful, thanks to your explanation I have been able to understand some things, but I have just realized that I don't need an array,
but what I need is a hash, do you have some example similar to this but with hash?, I am sorry I can't send code because I don't have nothing, I'm still studying.

I appreciate your help.

Regards,
Javier
KDJ
Posts: 243
Joined: Mon Sep 05, 2016 3:04 am
Location: Poland

Re: How to call function from .dll library?

Post by KDJ »

jparada wrote: ...do you have some example similar to this but with hash?...
No, I don't have any example with hash array passed from Harbour to C function.

To do something, you should give more data, at least:
1. Declaration of dll function (function name, type of return value, types of the parameters) and definitions of the structures if are used in this function.
2. Description of the parameters passed from Harbuor level to C function
3. Description of the value returned from C function to Harbour level.
jparada
Posts: 433
Joined: Fri Jan 23, 2009 5:18 pm

Re: How to call function from .dll library?

Post by jparada »

Hi Krzysztof,
Thanks for answering.
Krzysztof wrote:1. Declaration of dll function (function name, type of return value, types of the parameters) and definitions of the structures if are used in this function.
function name: altaProducto
parameter1 : integer Product Identifier, passed by reference
parameter2 : data structure

example data structure definition:

Code: Select all

field           type    length
codProducto	string	30	
descProducto	string	60
tipo            integer	
fechaRegistro	string	23
precio		double
unidad		string	30
Krzysztof wrote:2. Description of the parameters passed from Harbour level to C function
I'm not sure here, but I think it must be a hash, so

local idpdto := 0
local hdatos

hdatos := Hash()
hdatos["codProducto"] := "PDTO1"
hdatos["descProducto"] := "Nombre Producto"
hdatos["tipo"] := 1
hdatos["fechaRegistro"] := "06/09/2019"
hdatos["precio"] := 120.65
hdatos["unidad"] := "PIEZA"

altaProducto(@idpdto, hdatos)
Krzysztof wrote:3. Description of the value returned from C function to Harbour level.
return: integer values, 0 without error, different from 0, error code.

I hope that with this information you can give me some guidance.

I appreciate your time and your help.

Regards,
Javier
KDJ
Posts: 243
Joined: Mon Sep 05, 2016 3:04 am
Location: Poland

Re: How to call function from .dll library?

Post by KDJ »

jparada wrote: ...I'm not sure here, but I think it must be a hash...
No, it does not have to be a hash array.

This is sample code (compiled but not tested):

Code: Select all

#include "hmg.ch"

#define APROD_CPROD  1
#define APROD_DPROD  2
#define APROD_TIPO   3
#define APROD_FREG   4
#define APROD_PRECIO 5
#define APROD_UNIDAD 6
#define APROD_ALEN   6


FUNCTION Main()
  LOCAL nProdID := 0
  LOCAL aProd[APROD_ALEN]
  LOCAL nResult

  aProd[APROD_CPROD]  := "PDTO1"
  aProd[APROD_DPROD]  := "Nombre Producto"
  aProd[APROD_TIPO]   := 1
  aProd[APROD_FREG]   := "06/09/2019"
  aProd[APROD_PRECIO] := 120.65
  aProd[APROD_UNIDAD] := "PIEZA"

  nResult := my_AltaProducto(@nProdID, aProd)

  SWITCH nResult
    CASE 0 //no error
      MsgBox("Product ID: " + hb_NtoS(nProdID))
      EXIT
    CASE -1
      MsgBox("Error: can not load my_lib.dll library!")
      EXIT
    CASE -2
      MsgBox("Error: altaProducto function not found!")
      EXIT
    OTHERWISE
      MsgBox("Error code: " + hb_NtoS(nResult))
  ENDSWITCH

RETURN NIL


#pragma BEGINDUMP

#include "SET_COMPILE_HMG_UNICODE.ch"
#include "HMG_UNICODE.h"

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

typedef struct
{
  LPSTR  codProducto;
  LPSTR  descProducto;
  INT    tipo;
  LPSTR  fechaRegistro;
  DOUBLE precio;
  LPSTR  unidad;
} PROD;


        //my_AltaProducto(@nProdID, aProd)
HB_FUNC ( MY_ALTAPRODUCTO )
{
  HMODULE  hLib = LoadLibrary(_T("my_lib.dll"));
  INT      ProdID;
  PROD     ProdData;
  PHB_ITEM pArray;

  INT WINAPI (*pAltaProducto)(INT * ProdID, PROD * ProdData);

  if (hLib)
  {
    pAltaProducto = (INT WINAPI (*)(INT *, PROD *)) GetProcAddress(hLib, "altaProducto");

    if (pAltaProducto)
    {
      pArray = hb_param(2, HB_IT_ARRAY);

      ProdData.codProducto   = (LPSTR)  hb_arrayGetCPtr(pArray, 1);
      ProdData.descProducto  = (LPSTR)  hb_arrayGetCPtr(pArray, 2);
      ProdData.tipo          = (INT)    hb_arrayGetNI  (pArray, 3);
      ProdData.fechaRegistro = (LPSTR)  hb_arrayGetCPtr(pArray, 4);
      ProdData.precio        = (DOUBLE) hb_arrayGetND  (pArray, 5);
      ProdData.unidad        = (LPSTR)  hb_arrayGetCPtr(pArray, 6);

      hb_retni(pAltaProducto(&ProdID, &ProdData));
      hb_storni(ProdID, 1);
    }
    else
    {
      hb_retni(-2);
    }

    FreeLibrary(hLib);
  }
  else
  {
    hb_retni(-1);
  }
}

#pragma ENDDUMP
I still have questions:
What code page are you using?
What is the range of error codes returned by altaProducto function?
Can you share the dll file for testing?
User avatar
danielmaximiliano
Posts: 2632
Joined: Fri Apr 09, 2010 4:53 pm
Location: Argentina
Contact:

Re: How to call function from .dll library?

Post by danielmaximiliano »

Hola a todos: aprovecho este Post pra preguntar donde estoy fallando ya que tengo errores de compilacion y no encuentro cual es :?

codigo que encontre:

Code: Select all

/* ------------------------------
   Programa de prueba
   ------------------------------ */
#include "hmg.ch"
#include "hbdyn.ch" 
#define CRLF  INetCRLF()

PROCEDURE Main()
PUBLIC pDLL 
PUBLIC pVLCNew, pMediaNewLoc, pMediaNewPath, pPlayerNew, pSetHWND, pPlay

// Resolver funciones necesarias
   pVLCNew       := hb_DynCall( { "libvlc_new", pDLL }, HB_DYN_CTYPE_PTR, { HB_DYN_CTYPE_INT, HB_DYN_CTYPE_PTR } )
   pMediaNewLoc  := hb_DynCall( { "libvlc_media_new_location", pDLL }, HB_DYN_CTYPE_PTR, { HB_DYN_CTYPE_PTR, HB_DYN_CTYPE_STRING } )
   pMediaNewPath := hb_DynCall( { "libvlc_media_new_path", pDLL }, HB_DYN_CTYPE_PTR, { HB_DYN_CTYPE_PTR, HB_DYN_CTYPE_STRING } )
   pPlayerNew    := hb_DynCall( { "libvlc_media_player_new_from_media", pDLL }, HB_DYN_CTYPE_PTR, { HB_DYN_CTYPE_PTR } )
   pSetHWND      := hb_DynCall( { "libvlc_media_player_set_hwnd", pDLL }, HB_DYN_CTYPE_VOID, { HB_DYN_CTYPE_PTR, HB_DYN_CTYPE_LONG } )
   pPlay         := hb_DynCall( { "libvlc_media_player_play", pDLL }, HB_DYN_CTYPE_INT, { HB_DYN_CTYPE_PTR } )
PlayStream( "192.168.100.16:554" )
RETURN


//-----------------------------------------------------------
// Abrir cuadro de diálogo para seleccionar archivo local
//-----------------------------------------------------------
FUNCTION BrowseFile()
   LOCAL cFile := GetFile( { {"Videos", "*.mp4;*.avi;*.mkv;*.mov;*.flv"}, ;
                             {"Todos los archivos", "*.*"} }, ;
                             "Seleccionar archivo de video", "C:\videos\" )

   IF !Empty( cFile )
 // Main.txtSource.Value := cFile
 ENDIF
RETURN NIL

//-----------------------------------------------------------
// Inicializa VLC y reproduce un stream o archivo
//-----------------------------------------------------------
FUNCTION PlayStream( cSource )
   
   IF Empty( AllTrim( cSource ) )
      MsgStop( "Debe ingresar una URL o archivo" )
      RETURN NIL
   ENDIF

    IF Empty( pDLL )
      pDLL := hb_LibLoad( "libvlc.dll" )
      IF Empty( pDLL )
         ? "No se pudo cargar libvlc.dll" 
         RETURN NIL
      ENDIF
   ENDIF
   
   IF Empty( hVLC )
      hVLC := pVLCNew( 0, 0 )
   ENDIF

   IF File( cSource ) .OR. ( ":" $ cSource )
      hMedia := pMediaNewPath( hVLC, cSource )
   ELSE
      hMedia := pMediaNewLoc( hVLC, cSource )
   ENDIF

   hPlayer := pPlayerNew( hMedia )
   pSetHWND( hPlayer, GetControlHandle( "frm1", "Main" ) )
   pPlay( hPlayer )
RETURN NIL

//-----------------------------------------------------------
// Pause / Resume
//-----------------------------------------------------------
FUNCTION PauseStream()
   LOCAL pPause := hb_DynCall( { "libvlc_media_player_pause", "libvlc.dll" }, HB_DYN_CTYPE_VOID, { HB_DYN_CTYPE_PTR } )
   IF !Empty( hPlayer )
      pPause( hPlayer )
   ENDIF
RETURN NIL

//-----------------------------------------------------------
// Stop
//-----------------------------------------------------------
FUNCTION StopStream()
   LOCAL pStop := hb_DynCall( { "libvlc_media_player_stop", "libvlc.dll" }, HB_DYN_CTYPE_VOID, { HB_DYN_CTYPE_PTR } )
   IF !Empty( hPlayer )
      pStop( hPlayer )
   ENDIF
RETURN NIL

//-----------------------------------------------------------
// Volumen + / -
//-----------------------------------------------------------
FUNCTION VolumeUp()
   LOCAL pGetVol := hb_DynCall( { "libvlc_audio_get_volume", "libvlc.dll" }, HB_DYN_CTYPE_INT, { HB_DYN_CTYPE_PTR } )
   LOCAL pSetVol := hb_DynCall( { "libvlc_audio_set_volume", "libvlc.dll" }, HB_DYN_CTYPE_INT, { HB_DYN_CTYPE_PTR, HB_DYN_CTYPE_INT } )
   LOCAL nVol
   IF !Empty( hPlayer )
      nVol := pGetVol( hPlayer )
      pSetVol( hPlayer, Min( 200, nVol + 10 ) ) // máximo 200%
   ENDIF
RETURN NIL

FUNCTION VolumeDown()
   LOCAL pGetVol := hb_DynCall( { "libvlc_audio_get_volume", "libvlc.dll" }, HB_DYN_CTYPE_INT, { HB_DYN_CTYPE_PTR } )
   LOCAL pSetVol := hb_DynCall( { "libvlc_audio_set_volume", "libvlc.dll" }, HB_DYN_CTYPE_INT, { HB_DYN_CTYPE_PTR, HB_DYN_CTYPE_INT } )
   LOCAL nVol
   IF !Empty( hPlayer )
      nVol := pGetVol( hPlayer )
      pSetVol( hPlayer, Max( 0, nVol - 10 ) )
   ENDIF
RETURN NIL

//-----------------------------------------------------------
// Fullscreen On/Off
//-----------------------------------------------------------
FUNCTION ToggleFullScreen()
   LOCAL pToggle := hb_DynCall( { "libvlc_toggle_fullscreen", "libvlc.dll" }, HB_DYN_CTYPE_VOID, { HB_DYN_CTYPE_PTR } )
   IF !Empty( hPlayer )
      pToggle( hPlayer )
   ENDIF
RETURN NIL

el error :
hbmk2: Harbour: Compilando m¢dulos...
Harbour 3.2.0dev (r1703241902)
Copyright (c) 1999-2016, http://harbour-project.org/
hbmk2: Compilando...
hbmk2: Enlazando... hmgvlc.exe
.hbmk/win/mingw/Main.o:Main.c:(.data+0x178): undefined reference to `HB_FUN_PVLCNEW'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x198): undefined reference to `HB_FUN_PMEDIANEWPATH'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x1b8): undefined reference to `HB_FUN_PMEDIANEWLOC'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x1c8): undefined reference to `HB_FUN_PPLAYERNEW'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x1e8): undefined reference to `HB_FUN_PSETHWND'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x208): undefined reference to `HB_FUN_PPLAY'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x228): undefined reference to `HB_FUN_PPAUSE'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x248): undefined reference to `HB_FUN_PSTOP'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x268): undefined reference to `HB_FUN_PGETVOL'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x278): undefined reference to `HB_FUN_PSETVOL'
.hbmk/win/mingw/Main.o:Main.c:(.data+0x2c8): undefined reference to `HB_FUN_PTOGGLE'
collect2.exe: error: ld returned 1 exit status
hbmk2[hmgvlc]: Error: Ejecutando enlazador. 1
gcc.exe .hbmk/win/mingw/Main.o .hbmk/win/mingw/_hbmkaut_Main.o C:/Temp/HmgVlc/_temp.o -pthread -static-libgcc -static-libstdc++ -static -lpthread -mwindows -Wl,--start-group -lhmg -lcrypt -ledit -leditex -lgraph -lini -lreport -lhfcl -lmsvfw32 -lvfw32 -lhbmysql -lmysql -lhbfimage -lhbpgsql -lsddmy -lhbvpdf -lhbct -lhbwin -lhbmzip -lminizip -lhbmemio -lhbmisc -lhbtip -lsqlite3 -lhbsqlit3 -lsddodbc -lrddsql -lhbodbc -lodbc32 -lhbhpdf -lhbnetio -lxhb -lpng -llibhpdf -lhbzebra -lhbextern -lhbdebug -lhbvmmt -lhbrtl -lhblang -lhbcpage -lgtcgi -lgtpca -lgtstd -lgtwin -lgtwvt -lgtgui -lhbrdd -lhbuddall -lhbusrrdd -lrddntx -lrddcdx -lrddnsx -lrddfpt -lhbrdd -lhbhsx -lhbsix -lhbmacro -lhbcplr -lhbpp -lhbcommon -lhbmainwin -lkernel32 -luser32 -lgdi32 -ladvapi32 -lws2_32 -liphlpapi -lwinspool -lcomctl32 -lcomdlg32 -lshell32 -luuid -lole32 -loleaut32 -lmpr -lwinmm -lmapi32 -limm32 -lmsimg32 -lwininet -lhbpcre -lhbzlib -Wl,--end-group -ohmgvlc.exe -LC:/hmg.3.4.4/harbour/lib/win/mingw -LC:/hmg.3.4.4/lib

hbmk2: Error: Funci¢n(es) referenciada, no encontrada, pero desconocida:
PVLCNEW(), PMEDIANEWPATH(), PMEDIANEWLOC(), PPLAYERNEW(), PSETHWND(),
PPLAY(), PPAUSE(), PSTOP(), PGETVOL(), PSETVOL(), PTOGGLE()
*´¨)
¸.·´¸.·*´¨) ¸.·*¨)
(¸.·´. (¸.·` *
.·`. Harbour/HMG : It's magic !
(¸.·``··*

Saludos / Regards
DaNiElMaXiMiLiAnO

Whatsapp. := +54901169026142
Telegram Name := DaNiElMaXiMiLiAnO
Post Reply