Apelarea DLL-urilor

In lectia anterioara am invatat cum se creaza un DLL. Daca ati urmat pasii indicati in lectia anterioara ar trebui sa aveti deja un DLL numit Exemplu.dll care contine functia Factorial, pe care vom invata in cele ce urmeaza cum se apeleaza. Pentru aceasta o sa invatam functiile care le pune la dispozitie AutoIt pentru lucrul cu bibliotecile de functii (DLLs).

 

1.  DllOpen

Cu aceasta functie deschidem un fisier DLL pentru folosire. Are ca parametru un string care reprezinta numele fisierului. Functia va returna un handle, care se poate folosi ulterior cu functiile DllCall si DllClose, in caz de succes sau valoarea -1 in caz de eroare.

 

 

2. DllCall

Apeleaza o functie pe care o contine un fisier DLL. Functia are un numar variabil de parametri, in acord cu numarul de parametri pe care functia apelata ii are. Primul parametru este numele fisierului sau un handle (obtinut apeland functia DllOpen), al doilea parametru reprezinta tipul de date pe care functia apelata il returneaza, al treilea parametru este un string care contine numele functiei apelate. In continuare parametri sunt optionali si sunt secvente alternative care specifica tipul de date si datele pasate ca parametri ai functiei. Functia returneaza un vector ca si cel de mai jos:

$return[0] = valoarea returnata de functia apelata

$return[1] = parametrul 1

$return[2] = parametrul 2

$return[n] = parametrul n

 

Nota: Daca primul parametru al functiei DllCall nu este un handle atunci functia deschide DLL-ul, face apelul, dupa care inchide fisierul.

 

3. DllCallAddress

Apeleaza dinamic o functie la o adresa de memorie specifica.  Functia are un numar variabil de parametri, in acord cu numarul de parametri pe care functia apelata ii are. Primul parametru repezinta tipul de date returnat de functie, al doilea adresa de memorie a functiei. In continuare parametri sunt optionali si sunt secvente alternative care specifica tipul de date si datele pasate ca parametri ai functiei. Functia va returna un vector ca si in cazul functiei DllCall.

 

 


Tipurile de date valide pentru apelurile dll sunt cele din tabelul de mai jos:

Tip Detalii
none echivalent cu tipul void in C
BYTE unsigned 8 bit integer
BOOLEAN unsigned 8 bit integer
short 16 bit integer
USHORT unsigned 16 bit integer
WORD unsigned 16 bit integer
int 32 bit integer
long 32 bit integer
BOOL 32 bit integer
UINT unsigned 32 bit integer
ULONG unsigned 32 bit integer
DWORD unsigned 32 bit integer
INT64 64 bit integer
UINT64 unsigned 64 bit integer
ptr pointer general (void *)
HWND window handle (pointer)
HANDLE handle (pointer)
float numar in virgula mobila, precizie simpla
double numar in virgula mobila, precizie dubla
INT_PTR, LONG_PTR, LRESULT, LPARAM integer suficient de mare pentru a  pastra un pointer cand ruleaza versiunile AutoIt x86 sau x64
UINT_PTR, ULONG_PTR, DWORD_PTR, WPARAM unsigned integer suficient de mare pentru a  pastra un pointer cand ruleaza versiunile AutoIt x86 sau x64
str ANSI string (minim 65536 caractere sunt alocate)
wstr UNICODE string (minim 65536 caractere sunt alocate)
struct structura creata cu DllStructCreate()
* Adaugati * la finalul tipurilor de date pentru a fi pasate prin referinta (exemplu “int*” paseaza un pointer la o variabila de tip “int”)

 

Mai jos este prezentat tabelul de conversie a tipurilor de date Windows API in AutoIt:

WINDOWS API

AutoIt

LPCSTR/LPSTR

str

LPCWSTR/LPWSTR

wstr

LPVOID

ptr

LPxyz

xyz*

HINSTANCE

handle

HRESULT

long

LONGLONG/LARGE_INTEGER

INT64

ULONGLONG/ULARGE_INTEGER

UINT64

SIZE_T

ULONG_PTR

Nota: default, AutoIt apeleaza functiile folosind conventia “stdcall”. Pentru a apela o functie folosind conventia “cdecl” trebuie sa scrieti “:cdecl” dupa tipul de date care il returneaza functia.

 

 

4. DllClose

Inchide un DLL deschis anterior. Functia are ca parametru un handle returnat de functia DllOpen.

 

 

Pentru exemplificare o sa apelam functia Factorial din fisierul Exemplu.dll:

Nota: se presupune ca Exemplu.dll este in acelasi director cu scriptul, in caz contrar scrieti calea completa spre DLL.

 

Sa incercam acum sa aflam identificatorul procesului curent (PID) apeland functia GetCurrentProcessId din kernel32.dll:

In acest exemplu am folosit si functiile DllOpen si DllClose pentru exemplificare, dar de obicei se folosesc cand urmeaza mai multe apeluri ale functiilor continute de acelasi DLL. Se mai poate observa ca nu am folosit DWORD:cdecl  fiindca in acest caz se apeleaza functia folosind conventia de apelare __stdcall care e default in AutoIt.

 

Daca ati deschis vreodata un DLL cu un DLL Viewer cu siguranta stiti ca fiecare functie dintr-un DLL are o adresa. AutoIt dispune de o functie  in versiunea beta care permite apelul unei functii folosind adresa acesteia in loc de numele ei. Parametri functiei DllCallAddress sunt: tipul de date returnate, adresa functiei si daca este necesar, secvente tip date/variabila pentru parametri care ii are functia apelata.

Daca deschideti un DLL intr-un viewer ( in cazul meu DLL Export Viewer) o sa vedeti despre ce e vorba.

 

Insa cand apelati o functie dintr-un DLL folosind adresa ei, nu este recomandat sa copiati adresa dintr-un viewer pentru ca e posibil sa nu corespunda pe sisteme diferite dar puteti proceda in felul urmator:


* Pentru orice intrebari sau nelamuriri legate de curs sau limbajul AutoIt accesati sectiunea AutoIt a forumului SkullBox sau platforma de suport tehnic NetHelp.