How to call function from .dll library?

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

KDJ
Posts: 223
Joined: Mon Sep 05, 2016 3:04 am
Location: Poland
Been thanked: 262 times

Re: How to call function from .dll library?

Post by KDJ » Mon Jun 19, 2017 6:29 pm

Marek

I prepared C++ function instead of pure C.
Try how it works.

DllFunction.zip
(4.91 KiB) Downloaded 169 times

User avatar
bpd2000
Posts: 1080
Joined: Sat Sep 10, 2011 4:07 am
Location: India
Has thanked: 197 times
Been thanked: 96 times

Post by bpd2000 » Tue Jun 20, 2017 3:44 am

apais wrote:
Sun Jun 18, 2017 4:37 pm
Bravo !
Now I've learned how to traslate a Harbour array to a C structure.
Thank you
+1
BPD
Convert Dream into Reality through HMG

User avatar
mol
Posts: 3227
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 224 times
Been thanked: 127 times
Contact:

Post by mol » Tue Jun 20, 2017 4:36 pm

Hi Krzysztof!
Your new sample crashes. I can't find problem.
hb_out.log:

Code: Select all

Application Internal Error - D:\projekty\_DIBAL\KOMPLET\SDK_Biblioteki\SP_DibalSDK_V1.0.1.4\Dibalscop\DllFunction.exe
Terminated at: 2017-06-20 18:35:12
Unrecoverable error 6005: Exception error:

    Exception Code:C0000005 ACCESS_VIOLATION
    Exception Address:10021C7E
    EAX:00000000  EBX:0094FC7C  ECX:009E4BD1  EDX:00000000
    ESI:4F25E880  EDI:00000000  EBP:0094FAFC
    CS:EIP:0023:10021C7E  SS:ESP:002B:0094FAF8
    DS:002B  ES:002B  FS:0053  GS:002B
    Flags:00010206
    Exception Parameters: 00000001 00000000
    CS:EIP: 66 0F 7F 07 66 0F 7F 47 10 66 0F 7F 47 20 66 0F
    SS:ESP: 00000000 0094FB1C 10021CEB 00000000 4F25E880 00000000 00000000 100117DF 0094FC10 0094FBE8 1000672A 00000000 00000000 4F25E880 00000002 0094FC70

    C stack:
    EIP:     EBP:       Frame: OldEBP, RetAddr, Params...
    10021C7E 0094FAFC   0094FB1C 10021CEB 00000000 4F25E880 00000000 00000000 100117DF 0094FC10
    10021CEB 0094FB1C   0094FBE8 1000672A 00000000 00000000 4F25E880 00000002 0094FC70 FFFFFFFF 00000001 00000000
    1000672A 0094FBE8   0094FD08 00401AF8 0094FCD8 0094FC7C 00000001 0094FC10 00000002 00000001 FFFFFFFF 0049E99B
    00401AF8 0094FD08   00A1D35C 004A9FAA 0094FD3C 00000004 00000004 004B24FB 00A1DACC 00A1D98C 00A1D35C 004A8C11
    004A9FAA 00A1D35C   00A1D5A8 00A1D88C 00A1D56C 00A1D590 00000000 00A1BA7C 00A233D4 0000000A 006C9542 00A1B764
    00A1D88C 00A1D5A8   00A1DAF4 00A1F854 00A1F87C 00A1F8A4 00A1F8CC 00A1F8F4 00A1F91C 00A1F944 00A1F96C 00A1F994


Modules:
00400000 00344000 D:\projekty\_DIBAL\KOMPLET\SDK_Biblioteki\SP_DibalSDK_V1.0.1.4\Dibalscop\DllFunction.exe
77E30000 00183000 C:\WINDOWS\SYSTEM32\ntdll.dll
75660000 000E0000 C:\WINDOWS\System32\KERNEL32.DLL
75F80000 001A1000 C:\WINDOWS\System32\KERNELBASE.dll
74E40000 00077000 C:\WINDOWS\System32\ADVAPI32.dll
76220000 000BE000 C:\WINDOWS\System32\msvcrt.dll
778C0000 00041000 C:\WINDOWS\System32\sechost.dll
74D50000 000C1000 C:\WINDOWS\System32\RPCRT4.dll
748D0000 0001E000 C:\WINDOWS\System32\SspiCli.dll
748C0000 0000A000 C:\WINDOWS\System32\CRYPTBASE.dll
77BF0000 0005A000 C:\WINDOWS\System32\bcryptPrimitives.dll
77D40000 000E5000 C:\WINDOWS\System32\COMDLG32.DLL
74B30000 00211000 C:\WINDOWS\System32\combase.dll
6F050000 0020A000 C:\WINDOWS\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.14393.447_none_89c64d28dafea4b9\COMCTL32.DLL
77C50000 000E0000 C:\WINDOWS\System32\ucrtbase.dll
764B0000 0002B000 C:\WINDOWS\System32\GDI32.dll
76310000 00088000 C:\WINDOWS\System32\shcore.dll
77A90000 0015B000 C:\WINDOWS\System32\gdi32full.dll
75CA0000 0015F000 C:\WINDOWS\System32\USER32.dll
75BF0000 00015000 C:\WINDOWS\System32\win32u.dll
75750000 00046000 C:\WINDOWS\System32\SHLWAPI.dll
764E0000 013D9000 C:\WINDOWS\System32\SHELL32.dll
75BB0000 00036000 C:\WINDOWS\System32\cfgmgr32.dll
750A0000 0056E000 C:\WINDOWS\System32\windows.storage.dll
75610000 00045000 C:\WINDOWS\System32\powrprof.dll
76490000 0000D000 C:\WINDOWS\System32\kernel.appcore.dll
75C90000 0000F000 C:\WINDOWS\System32\profapi.dll
76130000 000EA000 C:\WINDOWS\System32\ole32.dll
74900000 00094000 C:\WINDOWS\System32\OLEAUT32.dll
75C10000 0007B000 C:\WINDOWS\System32\msvcp_win.dll
65EA0000 00006000 C:\WINDOWS\SYSTEM32\MSIMG32.DLL
63B30000 00023000 C:\WINDOWS\SYSTEM32\MSVFW32.DLL
6B650000 00024000 C:\WINDOWS\SYSTEM32\WINMM.DLL
74570000 0006A000 C:\WINDOWS\SYSTEM32\WINSPOOL.DRV
009D0000 00023000 C:\WINDOWS\SYSTEM32\WINMMBASE.dll
74550000 0001B000 C:\WINDOWS\SYSTEM32\bcrypt.dll
762E0000 00025000 C:\WINDOWS\System32\IMM32.DLL
52730000 002A3000 C:\WINDOWS\SYSTEM32\Msftedit.dll
6E060000 00075000 C:\WINDOWS\system32\uxtheme.dll
10000000 00059000 D:\projekty\_DIBAL\KOMPLET\SDK_Biblioteki\SP_DibalSDK_V1.0.1.4\Dibalscop\Dibalscop.dll

Called from DIBALSCOP_ITEMSSEND(0)
Called from MAIN(65) in DllFunction.prg
------------------------------------------------------------------------

KDJ
Posts: 223
Joined: Mon Sep 05, 2016 3:04 am
Location: Poland
Been thanked: 262 times

Post by KDJ » Tue Jun 20, 2017 5:46 pm

Marek

Can you share Dibalscop.dll for testing?


KDJ
Posts: 223
Joined: Mon Sep 05, 2016 3:04 am
Location: Poland
Been thanked: 262 times

Post by KDJ » Tue Jun 20, 2017 8:03 pm

Marek

We go back to C function. Try this:

DllFunction.zip
(3.79 KiB) Downloaded 209 times


User avatar
mol
Posts: 3227
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 224 times
Been thanked: 127 times
Contact:

Post by mol » Wed Jun 21, 2017 7:11 pm

It works Ok now!
I'll link it to my sale application and test in whole system.

jparada
Posts: 269
Joined: Fri Jan 23, 2009 5:18 pm
Been thanked: 3 times

Post by jparada » Mon Sep 02, 2019 9:46 pm

Hi,
I'm sorry for reactivating an old post, but the solution proposed by Krzysztof is almost what I need to do something very similar.

In my case, I also need to call a function of a dll, this function must receive only two parameters, an int that is the product number, this must be passed by reference and a structure where it receives all the product information,

So I am studying this code and trying to understand, apparently it is not so complex, but knowing nothing about C, I find it difficult to deduce what these lines do:

Code: Select all

LPSTR WINAPI (*pItemsSend)(SCALE * myScales, INT numScales, ITEM * myItems, INT numItems, INT showWindow, INT closeTime);
pItemsSend = (LPSTR WINAPI (*)(SCALE *, INT, ITEM *, INT, INT, INT)) GetProcAddress(hLib, "ItemsSend");
(and I think that knowing this is very important, I think it is the basis for all the code to work well)

And how I can modify this function for my needs.

So I am requesting your help for an explanation of this code and how I can modify to receive the int data as a reference and the structure.

I appreciate any guide, I've seen a lot of examples but I still can't figure out how to do it.

Regards,
Javier

KDJ
Posts: 223
Joined: Mon Sep 05, 2016 3:04 am
Location: Poland
Been thanked: 262 times

Post by KDJ » Tue Sep 03, 2019 7:31 pm

Javier

A brief explanation of the example above.


Definition of type SCALE (structure):

Code: Select all

typedef struct _SCALE
{
  INT    masterAddress;
  LPWSTR ipAddress;
  INT    txPort;
  INT    rxPort;
  LPWSTR model;
  LPWSTR display;
  LPWSTR section;
  INT    group;
  LPWSTR logsPath;
} SCALE;

Load Dibalscop.dll library into memory:

Code: Select all

HMODULE hLib = LoadLibraryA("Dibalscop.dll");

Declaration of the pointer to the function.:

Code: Select all

LPSTR WINAPI (*pItemsSend)(SCALE * myScales, INT numScales, ITEM * myItems, INT numItems, INT showWindow, INT closeTime);
LPSTR - type of return value (in this case the pointer to ANSI string),
WINAPI - standard calling convention for the function,
pItemsSend - pointer to the function,
(SCALE * myScales, INT numScales, ITEM * myItems, INT numItems, INT showWindow, INT closeTime) - function parameters and their types (6 parameters).
First parameter - myScales is pointer to the structure of type SCALE.
Next parameter - numScales is type of signed integer (32 bit).


Assigning the function address to the pointer (function name is ItemsSend, it should exist in Dibalscop.dll):

Code: Select all

pItemsSend = (LPSTR WINAPI (*)(SCALE *, INT, ITEM *, INT, INT, INT)) GetProcAddress(hLib, "ItemsSend");

ItemsSend function call with 6 arguments:

Code: Select all

pItemsSend(sc, nScales, it, nItems, hb_parl(3), hb_parni(4));

Function call and return the result to Harbour level:

Code: Select all

hb_retc(pItemsSend(sc, nScales, it, nItems, hb_parl(3), hb_parni(4)));

So if you want to use the function contained in .dll file, then you should know:
- file name,
- function name,
- type of returning value,
- list of parameters and their types,
- definition of type if type of result or parameter is not standard.

Post Reply