Cum se configurează smartphone-uri și PC-uri. Portal informativ

Funcții API ale limbajului Visual Basic. Ce este API

Cutie cu nisip

oțel, nurcă, carne de vită, hârtie 26 noiembrie 2012 la 13:59

Ce este API

Salutari!
În acest articol, ne vom uita la ce este un API, unde, cum și pentru ce este utilizat. Ne vom uita, de asemenea, la modul în care API-ul poate fi utilizat în dezvoltarea dvs. web și cum poate face viața mai ușoară unui programator web.

Deci, să începem cu o definiție. API (Application Programming Interface) este o interfață de programare, o interfață pentru crearea de aplicații. Într-un limbaj mai ușor de înțeles, API-ul este un cod gata făcut pentru a simplifica viața unui programator. API-ul a fost creat astfel încât programatorul să poată facilita cu adevărat sarcina de a scrie cutare sau cutare aplicație prin utilizarea unui cod gata făcut (de exemplu, funcții). Cunoscutul jQuery scris în JavaScript este, de asemenea, un fel de API. Dacă luăm în considerare acest exemplu special, atunci jQuery face mult mai ușor să scrieți cod. Ceea ce s-ar putea face în 30 de rânduri cu instrumentele JavaScript obișnuite, este scris prin jQuery în 5-6. Dacă luăm în considerare API-ul în general, atunci puteți găsi o mulțime de servicii care reprezintă soluții de dezvoltare. Cel mai faimos astăzi este serviciul code.google.com, care oferă aproximativ cincizeci de API-uri diferite! Aceasta este o interfață pentru crearea de aplicații Android și diverse API-uri pentru lucrul cu AJAX și diverse API-uri de aplicații pe care le puteți personaliza cu ușurință în felul dumneavoastră.

La urma urmei, are sens să scrii cod cu propriile mâini? De ce să lucrezi la ceea ce a fost deja creat? Are sens să refuzi soluții gratuite (și de fapt, ajutor gratuit) în dezvoltarea web? Dacă ați răspuns „NU” la toate aceste întrebări, atunci luați în considerare că înțelegeți esența API-ului.

Dar vreau și să clarific. Dezvoltatorii începători NU ar trebui să folosească soluții semifinite, deoarece nu vor face față sarcinii reale în viitor. Prin urmare, dacă sunteți un programator web începător, atunci nu utilizați semifabricate! Învață să gândești cu capul, construiește diverși algoritmi pentru a înțelege esența programării. Mai spun, adresându-mă deja tuturor, că API-ul nu este o soluție gata făcută, este un mediu, o interfață pentru crearea propriilor proiecte. Nu mănânci chiftele congelate de la magazin, nu? Le prăjiți mai întâi, nu? Această analogie surprinde foarte clar esența API-ului.

În general, am spus ce este API-ul, unde și cum este folosit, cel mai important, pentru ce. Vă doresc un studiu plăcut al programării web și înțelegerea profunzimii sale mai mari!

Fără etichete

Acest articol nu face obiectul comentariilor, deoarece autorul său nu este încă un membru cu drepturi depline al comunității. Veți putea contacta autorul numai după ce acesta va primi

Windows API - un set de funcții ale sistemului de operare

Abrevierea API pare multor programatori începători a fi foarte misterioasă și chiar înspăimântătoare. De fapt, interfața de programare a aplicațiilor (API) este doar un set gata făcut de funcții pe care dezvoltatorii de aplicații le pot folosi. În general, acest concept este echivalent cu ceea ce se numea mai des o bibliotecă de subrutine. Cu toate acestea, API este de obicei înțeles ca o categorie specială de astfel de biblioteci.

În timpul dezvoltării aproape oricărei aplicații destul de complexe (MyApplication), se formează un set de funcții interne specifice pentru utilizatorul final, care este utilizat pentru implementarea acestui program special, care se numește API-ul MyApplication. Cu toate acestea, adesea se dovedește că aceste funcții pot fi utilizate eficient pentru a crea alte aplicații, inclusiv de către alți programatori. În acest caz, autorii, pe baza strategiei de promovare a produsului lor, trebuie să decidă dacă deschid sau nu accesul la acest set pentru utilizatorii externi? Dacă răspunsul este da, în descrierea pachetului software, expresia apare ca o caracteristică pozitivă: „Pachetul include un set deschis de funcții API” (dar uneori pentru bani suplimentari).

Astfel, cel mai adesea un API este un set de funcții care fac parte dintr-o aplicație, dar în același timp disponibile pentru utilizare în alte programe. De exemplu, Excel, pe lângă interfața pentru utilizatorul final, are un set de funcții Excel API care pot fi utilizate, în special, atunci când se creează aplicații folosind VB.

În consecință, API-ul Windows este un set de funcții care face parte din sistemul de operare în sine și, în același timp, disponibil pentru orice altă aplicație, inclusiv pentru cele scrise folosind VB. În acest sens, analogia cu setul de întreruperi ale sistemului BIOS/DOS, care este de fapt un API DOS, este destul de justificată.

Diferența constă în faptul că compoziția funcțiilor API Windows, pe de o parte, este mult mai largă decât în ​​DOS, pe de altă parte, nu include multe dintre instrumentele de gestionare directă a resurselor informatice care erau disponibile pentru programatori din sistemul de operare anterior. În plus, accesul la API-ul Windows se realizează folosind apeluri procedurale obișnuite, iar funcțiile DOS sunt apelate printr-o instrucțiune specială de mașină a procesorului, care se numește întrerupere („întrerupere”).

De ce aveți nevoie de Win API pentru programatorii VB

În ciuda faptului că VB are o mare varietate de funcții, în procesul de dezvoltare mai mult sau mai puțin serios, se dovedește că capacitățile lor nu sunt adesea suficiente pentru a rezolva sarcinile necesare. În același timp, programatorii începători încep adesea să se plângă de deficiențele VB și să se gândească la schimbarea instrumentelor, fără a bănui că computerul lor are un set imens de instrumente și trebuie doar să știi cum să le folosești.

Când vă familiarizați cu API-ul Win, se dovedește că multe funcții VB încorporate nu sunt altceva decât un apel la procedurile de sistem corespunzătoare, dar sunt implementate doar sub forma sintaxei acestui limbaj. Având în vedere acest lucru, necesitatea de a utiliza API-ul este determinată de următoarele opțiuni:

  1. Funcții API care sunt complet implementate ca funcții VB încorporate. Cu toate acestea, uneori, în acest caz, este util să treceți la utilizarea API, deoarece aceasta poate uneori îmbunătăți semnificativ performanța (în special, datorită absenței conversiilor inutile ale parametrilor trecuți).
  2. Funcțiile VB încorporate implementează doar un caz special al funcției API corespunzătoare. Aceasta este o opțiune destul de comună. De exemplu, API-ul CreateDirectory este mai puternic decât instrucțiunea VB MkDir încorporată.
  3. Un număr mare de funcții API nu au deloc analogi în versiunea actuală a limbajului VB. De exemplu, nu puteți șterge un director folosind VB - trebuie să utilizați funcția DeleteDirectory pentru a face acest lucru.

De asemenea, trebuie subliniat faptul că unele funcții API (ponderea lor în API-ul Win este foarte mică) nu pot fi apelate din programele VB din cauza unui număr de restricții de limbă, de exemplu, din cauza lipsei capacității de a lucra cu adrese de memorie. Dar, în unele cazuri, tehnicile de programare non-triviale pot ajuta (în special, în cazul acelorași adrese).

Punctul de vedere personal al autorului este că, în loc să se extindă de la o versiune la o versiune a funcțiilor încorporate ale VB, ar trebui să se ofere o descriere bună a celor mai populare funcții API. În același timp, aș dori să sfătuiesc dezvoltatorii să nu aștepte o nouă versiune a instrumentului cu funcții avansate, ci să studieze cu atenție compoziția API-ului Win existent - este probabil ca caracteristicile de care aveți nevoie să fie implementate deja în versiunea din 1991 a VB 1.0.

Cum să înveți Win API

Aceasta nu este o întrebare atât de ușoară, având în vedere că numărul de funcții API Win32 este estimat la aproximativ 10.000 (nimeni nu știe numărul exact, nici măcar Microsoft).

VB (versiunile 4-6) include un fișier cu o descriere a declarațiilor Win API - WIN32API.TXT (mai multe despre utilizarea acestuia mai târziu). Dar, în primul rând, poate fi folosit pentru a obține informații despre scopul unei anumite funcții și parametrii acesteia numai prin numele mnemonice utilizate, iar în al doilea rând, lista de funcții din acest fișier este departe de a fi completă. La un moment dat (acum șapte ani) VB 3.0 avea fișiere speciale de ajutor care descriu funcțiile API-ului Win16. Cu toate acestea, deja în v.4.0 aceste informații utile cu o interfață convenabilă au dispărut.

Informații cuprinzătoare despre API-ul Win32 pot fi găsite în ajutorul Platform Software Development Kit, care se găsește în special pe CD-urile MSDN Library incluse cu VB 5.0 și 6.0 Enterprise Edition și Office 2000 Developer Edition. Totuși, nu este ușor să găsești acolo informațiile necesare și să le înțelegi. Ca să nu mai vorbim de faptul că toate descrierile de acolo sunt date în raport cu limbajul C.

Ghidul de renume mondial pentru învățarea programării API în mediul VB este cărțile celebrului expert american Daniel Appleman. Seria sa Dan Appleman's Visual Basic Programmer's Guide to the Windows API (pentru Win16, Win32, în legătură cu diferite versiuni de VB) a fost în mod constant un bestseller pentru programatorii VB din 1993. Ghidul de programator VB 5.0 al lui Dan Appleman pentru API-ul Win32, lansat în 1997, a fost adus autorului din SUA de un prieten care l-a găsit în prima librărie dintr-un orășel de provincie.

Această carte are peste 1.500 de pagini și include tehnici generale de programare VB API, precum și peste 900 de funcții. CD-ul însoțitor conține textul integral al cărții și toate exemplele de programare, plus câteva capitole suplimentare care nu sunt incluse în versiunea tipărită. În 1999, Dan Appleman a lansat o nouă carte, Win32 API Puzzle Book and Tutorial for Visual Basic Programers, care include informații despre alte 7600 de funcții (deși nu la fel de extinse).

Win API și Dynamic Link Library (DLL)

Setul de API Win este implementat ca DLL-uri dinamice. În plus, vom vorbi de fapt despre tehnologia de utilizare a DLL-urilor în mediul VB folosind exemplul de biblioteci care fac parte din API-ul Win. Cu toate acestea, când vorbim despre DLL-uri, există câteva lucruri importante de reținut.

În acest caz, prin DLL înțelegem varianta tradițională a bibliotecilor binare dinamice, care oferă aplicațiilor acces direct la procedurile necesare - subrutine sau funcții (la fel cum se întâmplă la apelarea procedurilor în interiorul unui proiect VB). Astfel de biblioteci pot fi create folosind diferite instrumente: VC ++, Delphi, Fortran, cu excepția VB (vom vedea ce va apărea în versiunea 7.0) - acesta din urmă poate crea doar DLL-uri ActiveX, care sunt accesate prin interfața OLE Automation.

De obicei, fișierele din bibliotecă de linkuri dinamice au o extensie .DLL, dar acest lucru nu este deloc necesar (pentru Win16, extensia .EXE a fost adesea folosită); Driverele de dispozitive externe sunt identificate cu .DRV.

După cum am observat deja, este destul de dificil să determinați numărul exact de API-uri Windows și fișierele care le conțin, dar toate sunt situate în directorul de sistem. În acest sens, este mai bine să evidențiați compoziția bibliotecilor incluse în nucleul sistemului de operare și bibliotecile principale cu funcții suplimentare cheie.

Și acum câteva sfaturi.

Sfat 1: asigurați-vă că anunțul dvs. DL este formatat corect L-proceduri

Însuși apelul la procedurile DLL din program arată exact la fel ca la procedurile Visual Basic „obișnuite”, de exemplu:

Apelați DllName([lista de argumente])

Cu toate acestea, pentru a utiliza funcții DLL externe (inclusiv API-ul Win), acestea trebuie să fie declarate în program folosind declarația Declare, care arată astfel:

Declarați Sub LibProcedureName _ „LibraryName” _ [[([ArgumentList])]

Declarare Function FunctionName _ Lib "LibraryName" _ [[([ArgumentList])]

Aici, elementele opționale ale operatorului sunt date între paranteze drepte, variabilele de expresie sunt în cursive, restul cuvintelor sunt cuvinte cheie. Sistemul de ajutor are o descriere destul de bună a sintaxei operatorului, așa că deocamdată vom face doar câteva puncte.

Declarațiile de funcții externe trebuie plasate în secțiunea Declarații generale a modulului. Dacă îl plasați într-un modul de formular, atunci trebuie să specificați cuvântul cheie Private (această declarație va fi disponibilă doar în interiorul acestui modul) - aceasta este restricția pentru toate procedurile modulului de formular.

Setul de API Win32 este implementat doar ca funcții (API-ul Win16 avea o mulțime de rutine Sub). În cea mai mare parte, acestea sunt funcții de tip Long, care returnează cel mai adesea codul de finalizare a operațiunii.

Declarația Declare a apărut în MS Basic pe vremea DOS și a fost folosită și pentru a declara procedurile interne ale proiectului. În Visual Basic, acest lucru nu este necesar, deoarece declararea procedurilor interne este automat declarația lor Sub sau Funcție. Față de Basic/DOS, este obligatoriu să se precizeze în noua descriere numele fișierului de bibliotecă în care se află procedura necesară. Bibliotecile Wip API sunt situate în directorul de sistem Windows, așa că este suficient să dați doar numele fișierului. Dacă accesați un DLL care se află într-o locație arbitrară, trebuie să notați calea completă către acest fișier.

Descrierea instrucțiunii Declare ocupă de obicei destul de mult spațiu și nu se încadrează pe o singură linie din fereastra de cod. Prin urmare, vă recomandăm să urmați o schemă specifică de întrerupere a liniilor atunci când scrieți aplicații, de exemplu:

Declarați funcția GetTempPath _ Lib "kernel32" Alias ​​​​"GetTempPathA" _ (ByVal nBufferLength As Long, _ ByVal lpBuffer As String) As Long

În acest caz, toate elementele principale ale descrierii sunt separate în rânduri diferite și, prin urmare, sunt bine citite.

Sfat 2: Fiți deosebit de atenți când lucrați cu funcții DLL

Utilizarea Win API și a diferitelor funcții DLL extinde semnificativ funcționalitatea VB și îmbunătățește adesea performanța programelor. Cu toate acestea, răsplata pentru aceasta este riscul de a reduce fiabilitatea aplicației, mai ales în procesul de depanare a acesteia.

Unul dintre cele mai importante avantaje ale mediului VB este fiabilitatea procesului de programare: funcționând sub controlul interpretului, codul programului nu poate perturba teoretic funcționarea Windows și VB în sine. Este posibil ca programatorul să nu fie foarte atent la corectitudinea transmiterii parametrilor către funcțiile apelate - astfel de erori vor fi detectate cu ușurință de către interpret însuși fie în procesul de traducere a codului, fie în timpul executării acestuia. În cel mai neplăcut caz, modul de procesare va fi pur și simplu întrerupt și cu o indicație despre unde și de ce a apărut eroarea.

Utilizarea directă a funcțiilor Windows API sau a altor DLL-uri elimină un astfel de control asupra transferului de date și execuției codului în afara mediului VB. Prin urmare, o eroare în accesarea funcțiilor externe poate duce la inoperabilitatea atât a VB, cât și a sistemului de operare. Acest lucru este valabil mai ales în stadiul dezvoltării programului, când prezența erorilor este destul de naturală. Astfel, prin aplicarea posibilităților mai largi ale funcțiilor stratului de bază al sistemului, programatorul își asumă responsabilitatea pentru corectitudinea aplicării acestora.

Problema este exacerbată de faptul că diferitele limbaje de programare folosesc moduri diferite de transmitere a parametrilor între proceduri. (Mai exact, diferite metode de trecere sunt utilizate în mod implicit, deoarece multe limbi pot accepta mai multe metode.) API-urile Win sunt implementate în C/C++ și folosesc convenții de transmitere a parametrilor C/C++, care sunt diferite de ceea ce este folosit pentru VB. .

În acest sens, trebuie menționat că apariția analogilor funcțiilor API încorporate în VB este justificată de adaptarea acestora din urmă la sintaxa VB și implementarea mecanismului de control al schimbului de date corespunzător. De asemenea, rețineți că în etapa de depanare experimentală a aplicației, la crearea unui modul executabil, este mai bine să utilizați opțiunea de compilare P-code în loc de Native Code (cod mașină). În primul caz, programul va rula sub controlul unui interpret - mai lent decât codul mașinii, dar mai fiabil în ceea ce privește posibilele efecte eronate asupra sistemului de operare și oferind un mod mai convenabil pentru detectarea eventualelor erori.

Sfatul 3: Cele zece sfaturi ale lui Dan Appleman pentru o programare API fiabilă în VB

Utilizarea unei funcții API necesită o programare mai atentă, folosind unele dintre metodele mai necunoscute de apelare a procedurilor (comparativ cu VB). Vom continua să abordăm aceste probleme în cele ce urmează. Și acum iată un rezumat al sfaturilor lui Dan Appleman pe această temă (prima lor versiune a apărut în 1993), cu câteva dintre completările și comentariile noastre.

1. Amintiți-vă de ByVal. Cea mai frecventă greșeală făcută la accesarea funcțiilor API și DLL este utilizarea incorectă a cuvântului cheie ByVal: fie uită să-l seteze, fie, dimpotrivă, îl setează atunci când nu este necesar.

Aceste exemple arată efectul instrucțiunii ByVal asupra trecerii parametrilor

Tipul de parametru Cu ByVal Fara ByVal
Întreg Un număr întreg de 16 biți este împins în stivă. Adresa de 32 de biți a unui număr întreg de 16 biți este împinsă în stivă.
Lung Un număr întreg de 32 de biți este împins în stivă. Adresa de 32 de biți a unui număr întreg de 32 de biți este împinsă în stivă.
Şir Șirul este convertit în formatul folosit în C (date și un octet nul final). Adresa de 32 de biți a liniei noi este împinsă în stivă Descriptorul VB al șirului este împins pe stivă. (Asemenea mânere nu sunt niciodată folosite de API-ul Windows în sine și sunt recunoscute doar în DLL-urile implementate special pentru VB.)

Trebuie amintit aici că transferul parametrilor în orice sistem de programare, inclusiv VB, se realizează în două moduri principale: prin referință (ByRef) sau prin valoare (ByVal). În primul caz, adresa variabilei este transmisă (această opțiune este utilizată implicit în VB), în al doilea - valoarea acesteia. Diferența fundamentală constă în faptul că, cu ajutorul unei referințe, valoarea modificată a parametrului transmis este returnată programului apelant.

Pentru a înțelege acest lucru, efectuați un experiment folosind următoarele programe:

Dim v As Integer v = 2 Apelați MyProc(v) MsgBox „v = “ & v Sub MyProc (v As Integer) v = v + 1 End Sub

Când rulați acest exemplu, veți primi un mesaj cu valoarea variabilei egală cu 3. Faptul este că, în acest caz, adresa variabilei v, creată fizic în programul apelant, este transmisă subrutinei MyProc. Acum schimbați descrierea procedurii în

Sub MyProc (ByVal v Ca întreg)

Ca urmare, atunci când rulați testul, veți obține v = 2, deoarece numai valoarea inițială a variabilei este transmisă procedurii - rezultatul operațiilor efectuate asupra acesteia nu este returnat programului apelant. De asemenea, puteți modifica modul de trecere prin valoare folosind instrucțiunea Call, după cum urmează:

Sub MyProc (v As Integer) ... Apelați MyProc((v)) ‘ (v) - parantezele indică modul pass-by-value _.

Cu toate acestea, atunci când se face referire la procedurile VB interne, utilizarea cuvântului cheie ByVal în instrucțiunea Call este interzisă - sunt folosite în schimb paranteze. Aceasta are propria sa explicație.

În cazul clasic (C, Fortran, Pascal), diferența dintre modurile ByRef și ByVal depinde de ceea ce exact este plasat pe stiva de schimb de date - adresa variabilei sau valoarea acesteia. Basic folosește din punct de vedere istoric o variantă a emulării software ByVal - adresa este întotdeauna pe stivă, dar numai atunci când trece prin valoare este creată o variabilă temporară pentru aceasta. Pentru a distinge între aceste două opțiuni (clasică și de bază), sunt folosite moduri diferite de a descrie modul ByVal. Rețineți că emularea modului ByVal în VB oferă o fiabilitate mai mare a programului: confundând forma apelului, programatorul riscă doar ca valoarea corectată a variabilei să fie returnată (sau să nu fie returnată) programului apelant. În versiunea „clasică”, totuși, o astfel de confuzie poate duce la o eroare fatală la executarea procedurii (de exemplu, când se folosește o valoare variabilă egală cu, să zicem, zero în locul unei adrese de memorie).

Funcțiile DLL sunt implementate conform principiilor „clasice” și, prin urmare, necesită o descriere obligatorie a modului în care datele sunt schimbate cu fiecare dintre argumente. Acesta este scopul declarațiilor de funcție prin descrierea Declare (mai precis, lista de argumente transmise). Cea mai obișnuită modalitate de a transmite parametrii unei funcții API sau DLL Windows este utilizarea cuvântului cheie ByVal. Mai mult, poate fi setat atât în ​​declarația Declare, cât și direct la apelarea funcției.

Consecințele trecerii incorecte ale parametrilor sunt ușor de prezis. Dacă primiți o adresă evident invalidă, veți primi un mesaj GPF (General Protection Fault). Dacă funcția primește o valoare care corespunde unei adrese valide, atunci funcția API se va accesa cu crawlere în zona altcuiva (de exemplu, în kernelul Windows) cu toate consecințele catastrofale care decurg.

2. Verificați tipul parametrilor trecuți. La fel de important este numărul și tipul corect de parametri trecuți. Argumentele declarate în Declarare trebuie să se potrivească cu parametrii așteptați din funcția API. Cea mai frecventă eroare în transmiterea parametrilor este legată de diferența dintre NULL și un șir de lungime zero - amintiți-vă că nu sunt același lucru.

3. Verificați tipul de returnare.

VB este destul de tolerant cu nepotrivirile tipului de returnare a funcției, deoarece valorile numerice sunt de obicei returnate prin registre, mai degrabă decât prin stivă. Următoarele reguli vor ajuta la determinarea valorii corecte returnate de o funcție API:

  • O funcție DLL care nu returnează o valoare (analog cu void în „C”) trebuie să fie declarată ca sub VB.
  • o funcție API care returnează o valoare întreagă (Integer sau Long) poate fi definită fie ca Sub, fie ca Funcție care returnează o valoare de tipul adecvat.
  • Niciuna dintre funcțiile API nu returnează numere în virgulă mobilă, dar unele DLL-uri pot returna un astfel de tip de date.

4. Utilizați construcția „As Any” cu mare grijă. Multe funcții API Windows au capacitatea de a accepta parametri de diferite tipuri și de a folosi constructul As Any (interpretarea tipului se realizează în funcție de valoarea altor parametri trecuți).

O soluție bună în acest caz ar fi să folosiți mai multe aliasuri de funcție, creând două sau mai multe declarații pentru aceeași funcție, fiecare declarație specificând parametrii de un anumit tip.

5. Nu uitați să inițializați șirurile. Există multe funcții în API-ul Win care returnează informații prin încărcarea datelor în buffer-uri de șir transmise ca parametru. În programul dvs., puteți părea că faceți totul corect: nu uitați de ByVal, transmiteți corect parametrii funcției. Dar Windows nu poate verifica cât de mare este dimensiunea memoriei alocate pentru șir. Rândul trebuie să fie suficient de mare pentru a găzdui toate datele care pot fi plasate în el. Este responsabilitatea programatorului VB să rezerve un buffer de dimensiunea corectă.

Rețineți că pe Windows pe 32 de biți, șirurile sunt convertite din Unicode (codare pe dublu octet) în ANSI (pe un singur octet) și invers, ținând cont de setările naționale ale sistemului. Prin urmare, pentru rezervarea bufferelor, uneori este mai convenabil să folosiți matrice de octeți în loc de variabile șir. (Mai multe despre aceasta vor fi discutate mai jos.)

De cele mai multe ori, funcțiile Win API vă permit să definiți singur dimensiunea maximă a blocului. În special, uneori, aceasta necesită apelarea unei alte funcții API care va „provoca” dimensiunea blocului. De exemplu, GetWindowTextLength vă permite să determinați dimensiunea șirului necesară pentru a găzdui titlul ferestrei returnat de funcția GetWindowText. În acest caz, Windows se asigură că nu ieșiți din limite.

6. Asigurați-vă că utilizați Opțiunea explicită.

7. Verificați cu atenție valorile parametrilor și valorile returnate. VB are capacități bune de verificare a tipului. Aceasta înseamnă că atunci când încercați să transmiteți un parametru nevalid unei funcții VB, cel mai rău lucru care se poate întâmpla este că primiți un mesaj de eroare de la VB. Dar acest mecanism, din păcate, nu funcționează la accesarea funcțiilor Windows API.

Windows 9x are un sistem îmbunătățit de verificare a parametrilor pentru majoritatea funcțiilor API. Prin urmare, prezența unei erori în date, de obicei, nu provoacă o eroare fatală, dar nu este atât de ușor să determinați ce a cauzat-o.

Aici vă putem sfătui să utilizați mai multe moduri de a depana acest tip de eroare:

  • utilizați depanarea pas cu pas sau comanda Debug.Print pentru a inspecta fiecare apel suspect de funcție API. Verificați rezultatele acestor apeluri pentru a vă asigura că totul este OK și funcția a ieșit cu grație;
  • utilizați un depanator Windows precum CodeView și o versiune de depanare a Windows (furnizată în SDK-ul Windows). Aceste instrumente pot detecta o eroare de parametru și cel puțin pot determina ce funcție API cauzează eroarea;
  • utilizați instrumente suplimentare de la terți pentru a verifica tipurile de parametri și validitatea valorilor acestora. Astfel de instrumente nu numai că pot găsi erori de parametri, ci chiar pot indica linia de cod VB unde a apărut eroarea.

În plus, este necesar să verificați rezultatul execuției funcției API.

8. Amintiți-vă că numerele întregi în VB și în Windows nu sunt același lucru.În primul rând, trebuie să rețineți că termenul „Integer” în VB se referă la un număr de 16 biți, în documentația Win 32 - un număr de 32 de biți. În al doilea rând, numerele întregi (întregi și lungi) în VB sunt valori cu semn (adică un bit este folosit ca semn, restul sunt folosite ca mantise a unui număr), în Windows sunt folosite doar numere nenegative. Această circumstanță trebuie reținută atunci când formați parametrul transmis utilizând operații aritmetice (de exemplu, calculați adresa prin însumarea unor baze și decalaj). Funcțiile aritmetice standard VB nu sunt potrivite pentru aceasta. Cum să fii în acest caz, vom vorbi separat.

9. Acordați o atenție deosebită numelor de funcții. Spre deosebire de Win16, numele tuturor funcțiilor API Win32 sunt sensibile la utilizarea exactă a literelor mici și mari (nu a fost cazul în Win16). Dacă folosiți undeva o literă mică în loc de o literă mare sau invers, atunci funcția dorită nu va fi găsită. De asemenea, aveți grijă la utilizarea corectă a sufixului A sau W în funcțiile care preiau parametri șir. (Pentru mai multe despre aceasta, vezi mai jos.)

10. Salvează-ți munca des. Erorile legate de utilizarea incorectă a DLL și Win API pot duce la o prăbușire în mediul VB și, eventual, la întregul sistem de operare. Ar trebui să vă asigurați că codul pe care îl scrieți înainte de rularea testului este salvat. Cel mai simplu este să setați modulele de proiect să se înregistreze automat înainte de a rula proiectul în VB.

După ce ați citit sfatul anterior, ați putea crede că utilizarea funcțiilor Win API este o afacere riscantă. Într-o oarecare măsură, acest lucru este adevărat, dar numai în comparație cu programarea sigură oferită de VB însuși. Dar cu aplicarea lor pricepută și cunoașterea posibilelor capcane, acest risc este minim. În plus, este adesea pur și simplu imposibil să renunți complet la utilizarea API-ului Win - acestea vor fi în continuare necesare pentru orice dezvoltare serioasă.

În plus, mai devreme am menționat „capcanele” pentru o clasă largă de DLL. În cazul API-ului Win, totul este mult mai simplu, deoarece forma de apelare a acestor funcții este clar unificată aici. În acest sens, trebuie avute în vedere următoarele puncte cheie:

  1. Funcțiile Win32 API sunt exact funcții, adică proceduri de tip Function (au fost multe sub rutine în Win16 API). Acestea sunt toate funcțiile de tip Long, deci descrierile lor sunt scrise după cum urmează: Declarare Function name ... As Long ‘ tipul funcției _ este definit în mod explicit

    Declarați numele funcției& ‘ tipul funcției _ este definit cu sufix

    Apelarea funcției API arată astfel:

Rezultat& = ApiName& ([ ArgumentList]
  1. Cel mai adesea, valoarea returnată a unei funcții este codul de ieșire al operației. Mai mult, o valoare diferită de zero în acest caz înseamnă o finalizare normală, zero - o eroare. De obicei, (dar nu întotdeauna) puteți verifica natura erorii apelând funcția GetLastError. Descrierea acestei funcții este următoarea: Declarare Funcție GetLastError& Lib "kernel32" ()

    ATENŢIE! Când lucrați în VB, cel mai bine este să utilizați proprietatea LastDLLError a obiectului Err pentru a obține valoarea codului de eroare rafinat, deoarece VB uneori resetează funcția GetLastError între apelarea API-ului și continuarea execuției programului.

    Puteți interpreta codul returnat de GelLastError folosind constantele scrise în fișierul API32.TXT, cu nume care încep cu sufixul ERROR_.

    Cele mai tipice erori au următoarele coduri:

    • ERROR_INVALID_HANDLE = 6& - indicator nevalid
    • ERROR_CALL_NOT_IMPLEMENTED = 120& - apelați în Windows 9x o funcție disponibilă numai pentru Windows NT
    • ERROR_INVALID_PARAMETER = 87& - valoarea parametrului nevalidă

    Cu toate acestea, multe funcții returnează valoarea unui parametru solicitat (de exemplu, OpenFile returnează valoarea unui descriptor de fișier). În astfel de cazuri, eroarea este definită de o altă valoare specială Return&, cel mai frecvent 0 sau -1.

  2. API-urile Win32 folosesc modalități strict fixe de a transmite cele mai simple tipuri de date. a) ByVal ... Cât timp

    Variabilele lungi gestionează cel puțin 80% din trecerea argumentului. Rețineți că argumentul mereu este urmat de cuvântul cheie ByVal, care, printre altele, înseamnă că se efectuează un transfer de date unidirecțional - de la programul VB la funcția API.

    B) ByVal ... Ca șir

    Acest tip de transfer de date este, de asemenea, destul de comun și, de asemenea, cu un argument mereu Se aplică ByVal. Când este apelată o funcție API, adresa șirului este scrisă pe stivă, deci, în acest caz, este posibil schimbul de date în două sensuri. Există mai multe pericole de care trebuie să fii conștient atunci când lucrezi cu șiruri.

    Prima este că memoria este rezervată pentru un șir din programul de apelare, așa că dacă funcția API va umple șiruri, atunci înainte de a o apela, trebuie să creați un șir de dimensiunea necesară. De exemplu, funcția GetWindowsDirectory returnează calea către directorul Windows, care, prin definiție, nu trebuie să aibă mai mult de 144 de caractere. În consecință, apelul la această funcție ar trebui să arate cam așa:

    WinPath$ = Space$(144) „șir de rezervă în _ 144 caractere Rezultat& = GetWindowsDirectory& (WinTath$, 144) _ „buffer fill” Rezultat& - numărul real de caractere din numele directorului _ WinPath$ = Left$ (WinPath, Result&)

    A doua problemă este că atunci când funcția API este apelată, șirul sursă este convertit într-o reprezentare internă a acestuia și invers când funcția iese. Dacă la momentul Win16 această operațiune consta doar în adăugarea unui octet nul la sfârșitul șirului, atunci odată cu apariția Win32 s-a adăugat la aceasta transformarea codificării pe doi octeți Unicode în ANSI și invers. (Acest lucru a fost discutat în detaliu în articolul „Features of Working with String Variables in VB”, ComputerPress 10'99 și 01'2000). Deocamdată, rețineți că folosind construcția ByVal ... As String, puteți schimba doar șiruri de caractere cu date de caractere.

    C) ... Ca oricare

    Aceasta înseamnă că o anumită adresă de memorie tampon va fi împinsă în stivă, al cărei conținut va fi interpretat de funcția API, de exemplu, în funcție de valoarea altor argumente. Cu toate acestea, As Any poate fi folosit doar într-o instrucțiune Declare - o anumită variabilă trebuie definită ca argument atunci când este efectuat un anumit apel la funcție.

    D) ... Ca UserDefinedType

    O astfel de construcție este adesea folosită și atunci când este necesar să se facă schimb de date (în general în ambele direcții) folosind o structură. Acest construct este de fapt un fel de implementare concretă a formei de transfer As Any, doar că, în acest caz, funcția este setată la o structură fixă.

    Forma structurii de date este definită de o anumită funcție API și este responsabilitatea programatorului să o descrie și să o rezerve corect în programul apelant. Un astfel de design mereu folosit fără cuvintele ByVal, adică în acest caz, se realizează trecerea prin referință - adresa variabilei este scrisă în stivă.

Un exemplu de apelare a unei funcții API

Să ilustrăm cele de mai sus cu un exemplu de utilizare a două funcții de fișier utile - lopen și lread , care sunt descrise după cum urmează:

Declarare Funcție lread Lib „kernel32” _ Alias ​​​​“_lread” (_ ByVal lpFileName As String, _ ByVal wReadWrite As Long) As Long Declarare Funcție lread Lib „kernel32” _ Alias ​​​​“_lread” (_ ByVal hFile As Long, lpBuffer As Any, _ ByVal wBytes As Long) Cât timp

În VB, omologii lor - în acest caz, cei exacti - sunt operatorii Open și Get (pentru modul Binary). Să acordăm imediat atenție utilizării cuvântului cheie Alias ​​în declarația funcției - acesta este exact cazul când nu puteți face fără el. Numele de funcții reale din bibliotecă încep cu un caracter de subliniere (stil C tipic), care nu este permis în VB.

Operația de deschidere a fișierului ar putea arăta astfel:

Const INVALID_HANDLE_VALUE = -1 ' invalid _ handle value lpFileName$ = „D:\calc.bas” ' nume de fișier wReadWrite& = 2 ' citire-scriere mod hFile& = lopen(lpFileName$, wReadWrite&) _ ' definiți handle de fișier Dacă hFile& = INVALID_HANDLE_VALUE Apoi _ ' eroare de deschidere a fișierului ' Specificarea codului de eroare CodeError& = Err.LastDllError 'CodeError& = GetLastError _ ' acest construct nu funcționează End If

Aici trebuie să fiți atenți la două puncte:

  • ca valoare a funcției, obținem valoarea descriptorului de fișier. O eroare corespunde unei valori de -1;
  • doar în acest caz, apelul la funcția GetLastError nu funcționează - pentru a obține valoarea de eroare rafinată, am apelat la obiectul Err (am vorbit despre posibilitatea unei astfel de situații mai sus).

Apoi puteți citi conținutul fișierului, dar acest lucru presupune că programatorul trebuie să înțeleagă structura acestuia (la fel cum se întâmplă când lucrează cu fișiere binare arbitrare). În acest caz, apelul la funcția lread ar putea arăta astfel:

Dim MyVar As Single wBytes = lread (hFile&, MyVar, Len(MyVar) ' citind un număr real, 4 bytes ' wBytes este numărul de date citite efectiv, ' -1 este o eroare... Tastați MyStruct x As Single i As Integer End Type Dim MyVar As MyStruct wBytes = lread (hFile&, MyVar, Len(MyVar)) Structura de date citită, 6 octeți

Rețineți din nou că al doilea argument al funcției este transmis prin referință, restul după valoare.

Dim MyVar As String MyVar = Space$(10) 'variabilă de rezervă pentru 10 caractere wBytes = lread (hFile&, ByVal MyVar, Len(MyVar)) ' șirul de caractere citit, 10 caractere

Aici puteți vedea o diferență importantă față de exemplul anterior - o variabilă șir este neapărat însoțită de cuvântul cheie ByVal.

Citirea conținutului unui fișier dintr-o matrice (pentru simplitate, vom folosi o matrice de octeți unidimensională) se realizează după cum urmează:

Dim MyArray(1 To 10) As Byte wBytes = lread (hFile&, MyArray(1), _ Len(MyArray(1))* 10) ‘ citind 10 elemente de matrice

Specificând primul element al matricei ca argument, trecem adresa de la începutul zonei de memorie rezervată matricei. Evident, orice fragment al matricei poate fi completat în acest fel:

WBytes = lread (hFile&, MyArray(4), _ Len(MyArray(1))* 5) ' citește elementele matricei de la 4 la 8

Sfat 5: Folosiți alias pentru transmisiiși parametrii ca oricare

Aici, pe baza exemplului anterior, vom dezvălui esența celui de-al patrulea vârf al lui Dan Appleman.

Când lucrați cu funcția lread, trebuie să vă amintiți că atunci când o accesați folosind o variabilă șir, trebuie să utilizați cuvântul cheie ByVal (altfel mesajul despre o operațiune ilegală nu poate fi evitat). Pentru a fi în siguranță, puteți face o descriere specială suplimentară a aceleiași funcții care să funcționeze numai cu variabile șir:

Declarați funcția lreadString Lib "kernel32" _ Alias ​​​​"_lread" (_ ByVal hFile As Long, ByVal lpBuffer As String, _ ByVal wBytes As Long) As Long

Când lucrați cu această descriere, nu mai trebuie să specificați ByVal când accesați:

WBytes = lreadString (hFile&, MyVarString, _ Len(MyVarString)) '

S-ar părea că sintaxa operatorului Declare vă permite să faceți o astfel de declarație specială pentru o matrice:

Declarați funcția lreadString Lib „kernel32” Alias ​​„_lread” (_ ByVal hFile As Long, lpBuffer() As Byte, _ ByVal wBytes As Long) As Long

Cu toate acestea, recursul

WBytes = lreadArray(hFile&, MyArray(), 10)

duce inevitabil la o eroare fatală a programului.

Aceasta este o continuare a conversației despre particularitățile procesării variabilelor șir în Visual Basic: VB folosește o codificare Unicode pe doi octeți, Win API folosește o codificare ANSI pe un octet (mai mult, cu formatul adoptat în C, cu un octet nul la sfârșitul). În consecință, atunci când se utilizează variabile șir ca argument, conversia din Unicode în ANSI este întotdeauna efectuată automat la apelarea unei funcții API (mai precis, o funcție DLL) și invers la întoarcere.

Dezbaterea este simplă: variabilele șir pot fi folosite pentru a face schimb de date de caractere, dar nu pot fi folosite pentru a schimba informații binare arbitrare (cum a fost cazul versiunilor VB pe 16 biți). În acest din urmă caz, este mai bine să utilizați o matrice de octeți unidimensională.

După cum știți, tipul String poate fi folosit pentru a descrie o structură personalizată. În acest sens, trebuie reținut următoarele:

  • Este strict interzisă utilizarea următoarei construcții pentru a accesa API-ul Win: Type MyStruct x As Single s As String ‘ variabil length string End Type

    În cazul unui șir de lungime variabilă, un descriptor de șir este trecut ca parte a structurii, cu toate consecințele care decurg sub forma unei erori de execuție a programului.

  • Puteți utiliza un șir de lungime fixă ​​ca element de structură: Type MyStruct x As Single s As String*8 ‘ fixed length string End Type

În acest caz, se realizează conversia de codificare corespunzătoare.

Și ultima notă: nu puteți utiliza o matrice de variabile șir (atât cu lungime fixă, cât și cu lungime variabilă) atunci când accesați o funcție API în orice caz. În caz contrar, va fi garantată apariția unei „operațiuni ilegale”.

Este probabil să aveți o situație în care trebuie să vă scrieți propriile funcții DLL. Necesitatea acestui lucru va apărea inevitabil dacă utilizați tehnologia de programare mixtă - utilizarea a două sau mai multe limbaje de programare pentru a implementa o aplicație.

În acest sens, observăm că programarea mixtă este destul de comună pentru implementarea unei aplicații destul de complexe. Într-adevăr, fiecare limbă (mai precis, un sistem de programare bazat pe un limbaj) are propriile sale puncte tari și puncte slabe, așa că este destul de logic să folosim avantajele diferitelor instrumente pentru rezolvarea diferitelor probleme. De exemplu, VB - pentru crearea unei interfețe cu utilizatorul, C - pentru acces eficient la resursele sistemului, Fortran - pentru implementarea algoritmilor numerici.

Opinia autorului este următoarea: orice programare serioasă necesită ca dezvoltatorul să dețină cel puțin două instrumente. Desigur, în condițiile de astăzi ale unei diviziuni clare a muncii, este foarte dificil să fii un expert excelent chiar și în două sisteme, așa că schema „limbi principale și auxiliare” este mai logică. Ideea aici este că chiar și o mică cunoaștere a limbajului „auxiliar” (scrierea unor proceduri destul de simple) poate îmbunătăți foarte mult eficiența limbii „principale”. Rețineți că cunoașterea VB, cel puțin ca auxiliară, este astăzi o cerință aproape obligatorie pentru un programator profesionist. Apropo, în zilele DOS pentru orice programator, inclusiv Basic, era foarte de dorit să cunoască elementele de bază ale Assembler.

Într-un fel sau altul, dar chiar și în condițiile de lucru în grup, când fiecare programator este angajat în propria sa afacere specifică, toți participanții la proiect ar trebui să aibă o idee despre caracteristicile interfeței procedurale în diferite limbi. Și să știți că multe sisteme de programare (inclusiv VB), pe lângă interfața implicită, vă permit să utilizați alte metode extinse de apelare a procedurilor, care fac posibilă adaptarea interfeței la o altă limbă.

Când studiați interfața interprocedurală, ar trebui să acordați atenție următoarelor posibile „capcane”:

  • Diferite limbi pot folosi convenții diferite pentru scrierea identificatorilor. De exemplu, este obișnuit să folosiți un caracter de subliniere la începutul unui nume de procedură, ceea ce nu este permis în VB. Această problemă este ușor de rezolvat prin utilizarea cuvântului cheie Alias ​​în declarația Declare (consultați Sfatul 2-3, de exemplu).
  • Poate fi folosită o secvență diferită de scriere a argumentelor transmise stivei. De exemplu, pe vremea DOS (ca să fiu sincer - nu știu cum arată acum într-un mediu Windows), C a scris argumente de la sfârșitul listei, alte limbi​​​(Fortran, Pascal, Basic ) - de la inceput.
  • În mod implicit, sunt utilizate diferite principii pentru transmiterea parametrilor - prin referință sau după valoare.
  • Diverse principii pentru stocarea variabilelor șir. De exemplu, în C (precum și în Fortran și Pascal) lungimea unui șir este determinată de un octet nul la sfârșitul acestuia, în timp ce în Basic lungimea este scrisă explicit în descriptorul șirului. Desigur, trebuie să aveți în vedere posibilitatea de a utiliza diferite codificări de caractere.
  • La transferul de tablouri multidimensionale, trebuie amintit că există diverse opțiuni pentru conversia structurilor multidimensionale în cele unidimensionale (începând de la primul index sau de la ultimul, în raport cu tablourile bidimensionale - „pe rânduri” sau „pe coloane”. ”).

Având în vedere acest lucru, se pot face următoarele recomandări:

  • Utilizați cele mai simple și dovedite modalități de a transmite argumente funcțiilor DLL. Standardele adoptate pentru API-ul Win sunt destul de potrivite ca model.
  • Nu trece niciodată matrice de variabile șir.
  • Fiți foarte atenți la transmiterea variabilelor șir simple și a tablourilor multidimensionale.
  • Asigurați-vă că verificați funcționalitatea mecanismului de transmitere a argumentelor către și de la procedura apelată într-un mod special. Scrieți un test personalizat pentru a verifica transferul de date. Verificați separat dacă fiecare argument este transmis corect. De exemplu, dacă aveți o procedură cu mai multe argumente, verificați mai întâi corectitudinea transmiterii fiecărui parametru pentru o variantă cu un singur argument și abia apoi - pentru întreaga listă.

Dar dacă funcția DLL este deja scrisă, de exemplu, în Fortran, dar interfața sa de intrare nu se potrivește foarte bine în standardele VB de mai sus? Există două sfaturi aici. Mai întâi: scrieți o funcție DLL de testare și utilizați-o pentru a încerca să găsiți apelul potrivit din programul VB prin încercare și eroare. În al doilea rând: scrieți o procedură de adaptor în același Fortran care ar oferi o interfață simplă între VB și o funcție DLL cu transformarea structurilor de date simple în unele complexe (de exemplu, conversia unei matrice de octeți multidimensionale într-o matrice de șiruri).

Deci: utilizați funcțiile DLL. Dar fii vigilent...

ComputerPress 9 "2000

API-ul definește funcționalitatea pe care o oferă un program (modul, bibliotecă), în timp ce API-ul vă permite să faceți abstracție de la modul exact în care este implementată această funcționalitate.

Dacă un program (modul, bibliotecă) este considerat o cutie neagră, atunci API-ul este un set de „mânere” care sunt disponibile utilizatorului acestei casete, pe care acesta le poate întoarce și trage.

Componentele software interacționează între ele prin intermediul API-urilor. În acest caz, componentele formează de obicei o ierarhie - componentele de nivel înalt folosesc API-ul componentelor de nivel inferior, iar acestea, la rândul lor, folosesc API-ul componentelor de nivel inferior.

Conform acestui principiu, protocoalele pentru transmiterea datelor prin . Protocolul Internet standard (modelul de rețea OSI) conține 7 straturi (de la nivelul fizic al transmisiei pachetelor de biți la nivelul protocoalelor de aplicație precum HTTP și IMAP). Fiecare strat profită de funcționalitatea stratului de date anterior și, la rândul său, oferă funcționalitatea dorită stratului următor.

Este important de reținut că conceptul de protocol este apropiat ca înțeles de conceptul de API. Ambele sunt abstracții ale funcționalității, doar că în primul caz vorbim despre transferul de date, iar în al doilea - despre construirea de aplicații informatice.

API-ul bibliotecii de funcții și clase include o descriere semnăturiȘi semantica functiei.

Interfața de programare a aplicațiilor (API) este o interfață software pentru interacțiunea între sisteme care vă permite să:

  • Obțineți acces la serviciile de afaceri pentru întreprinderi
  • Schimb de informații între sisteme și aplicații
  • Simplificați comunicarea între companii, parteneri, dezvoltatori și clienți

Deschideți strategia API

Strategia API include:

  • Dezvoltarea de produse de afaceri bazate pe API-urile existente
  • Furnizarea de servicii interne pentru dezvoltatori
  • Modele de monetizare API pentru construirea de interacțiuni pe mai multe canale și creșterea profiturilor

Implementarea conceptului Open API ajută la transformarea unei afaceri, integrarea acesteia într-un ecosistem flexibil de proiecte de jucători de pe piață, crearea condițiilor pentru generarea constantă de idei noi și crearea de valoare suplimentară în gestionarea matricelor de date corporative.

Piața soluțiilor de integrare se dezvoltă în contextul evoluției API-urilor - de la EDI și SOAP la Web 2.0, care a început era API-urilor publice. Numărul de astfel de interfețe în următorii 3 ani poate crește de peste 50 de ori și poate ajunge la 1 milion. Acest lucru se datorează multi-canalului: canalele de interacțiune cu clienții trebuie să se schimbe odată cu acestea. Creșterea continuă a numărului de consumatori și a volumului de date a dus la apariția unei economii API care ajută la crearea modelelor de afaceri inovatoare bazate pe interfețe deschise pentru a utiliza activele și serviciile întreprinderii.

Semnătura funcției

Semnătura funcției- parte a declarației generale a funcției, permițând mijloacelor de traducere să identifice funcția printre altele. Diferite limbaje de programare au idei diferite despre semnătura unei funcții, care este, de asemenea, strâns legată de posibilitățile de supraîncărcare a funcției în aceste limbi.

Uneori se disting semnătură de apelȘi semnătură de implementare funcții. Semnătura apelului este de obicei compilată conform construcției sintactice a unui apel de funcție, ținând cont de semnătura domeniului de aplicare a acestei funcții, numele funcției, succesiunea de tipuri reale de argumente din apel și tipul de apel. rezultat. Semnătura de implementare implică, de obicei, unele elemente din construcția sintactică a declarației funcției: specificatorul de sfere a funcției, numele acesteia și succesiunea tipurilor de argumente formale.

De exemplu, în limbajul de programare C++, o funcție simplă este identificată în mod unic de către compilator prin numele și secvența tipurilor de argumente, care constituie semnătura funcției în acest limbaj. Dacă funcția este o metodă a unei clase, atunci și numele clasei va participa la semnătură.

De asemenea, trebuie menționat că un programator are adesea la dispoziție mai multe API-uri diferite pentru a obține același rezultat. În acest caz, fiecare API este de obicei implementat folosind API-uri ale componentelor software cu un nivel de abstractizare inferior.

De exemplu: pentru a vedea linia „Bună ziua, lume!” tot ce trebuie să faci este să creezi un document HTML cu un titlu minim și un corp simplu care să conțină șirul dat. Ce se întâmplă când browserul deschide acest document? Programul browser va transmite numele fișierului (sau un descriptor de fișier deja deschis) bibliotecii care procesează documente HTML, care, la rândul său, folosind API-ul sistemului de operare, va citi acest fișier și va înțelege dispozitivul său, apelează operațiuni precum „clear fereastra”, „scrieți în fontul selectat Hello, world!”, în timpul acestor operațiuni, biblioteca primitivă grafică se va întoarce la biblioteca interfeței ferestrei cu solicitările corespunzătoare, această bibliotecă se va întoarce deja la API-ul sistemului de operare cu solicitări precum „ pune-mă în tamponul plăcii video asta".

În același timp, există de fapt mai multe API-uri alternative posibile la aproape fiecare nivel. De exemplu: am putea scrie documentul sursă nu în HTML, dar în LaTeX, am putea folosi orice browser pentru afișare. Diferitele browsere folosesc în general biblioteci HTML diferite și, în plus, toate acestea pot fi (în general vorbind) construite folosind diferite biblioteci primitive și pe diferite sisteme de operare.

Principalele complexități ale sistemelor API stratificate existente sunt astfel:

  • Dificultate în portarea codului programului de la un sistem API la altul (de exemplu, la schimbarea sistemului de operare);
  • Pierderea funcționalității la trecerea de la un nivel inferior la unul superior. În linii mari, fiecare „strat” al API-ului este creat pentru a facilita implementarea unui set standard de operațiuni. Dar, în același timp, devine cu adevărat dificil, sau devine fundamental imposibil, să efectuați alte operațiuni pe care le oferă un nivel API mai scăzut.

Tipuri de API de bază

API-uri interne

  • Accesul la API este limitat la dezvoltatorii interni
  • Aplicațiile se adresează angajaților întreprinderii

Factori de afaceri:

  • Consecvența dezvoltării
  • Reducerea costurilor
  • Îmbunătățirea eficienței dezvoltării

API-uri pentru parteneri

  • API-urile sunt disponibile numai pentru un set limitat de parteneri de afaceri
  • Aplicații concepute pentru consumatorii finali și utilizatorii de afaceri

Factori de afaceri:

  • Automatizarea procesului de dezvoltare
  • Dezvoltarea parteneriatelor
  • Optimizarea procesului de interactiune cu partenerii

API-uri publice

Accesul este acordat oricărui dezvoltator extern Aplicațiile sunt destinate utilizatorilor finali

Factori de afaceri:

  • Dezvoltarea de noi servicii
  • Dezvoltarea ecosistemului
  • Interacțiune multicanal

Cele mai cunoscute API-uri

API-uri ale sistemului de operare

API-uri GUI

  • Direct3D (parte a DirectX)
  • DirectDraw (parte a DirectX)

API-urile pot fi atât distractive, cât și frustrante în același timp. Pe de o parte, interacționând cu alte aplicații, puteți crește considerabil acoperirea publicului și „efectul wow” al aplicației dumneavoastră. Pe de altă parte, aceasta include citirea de tone de documentație, învățarea despre strategiile de autentificare și analizarea mesajelor de eroare neinformative (sau chiar lipsă).

În primul rând, dacă încă nu înțelegeți pe deplin ce este un API (Application Programming Interface), citiți explicația lui Skillcrush și apoi prima parte a acestui articol pentru a vă prinde din urmă.

„API” este un concept incredibil de larg - de fiecare dată când aplicația ta „vorbește” cu o altă aplicație, se face printr-un fel de API. Componentele din cadrul propriei aplicații, cum ar fi diferite părți ale Rails, comunică, de asemenea, între ele prin intermediul unui API. Sunt subaplicații mai mult sau mai puțin independente care transmit datele de care fiecare are nevoie pentru a-și îndeplini sarcinile specifice. În lumea aplicațiilor, totul este un API!

Când creați aplicații cu funcționalitate front-end mai dinamică (atât aplicații Javascript cu o singură pagină, cât și aplicații simple cu apeluri AJAX separate), acestea vor comunica cu backend-ul Rails prin propriul dvs. API, care este de fapt doar o linie suplimentară sau două de cod. . , spunându-le controlorilor cum să difuzeze JSON sau XML în loc de HTML.

În acest tutorial, veți învăța cum să vă creați propriul API. În lecțiile ulterioare, vom trata cum să interacționăm cu API-urile altor aplicații. Lecțiile ar trebui să fie o bună trambulină pentru a învăța despre acest subiect, dar este puțin probabil să poată acoperi pe deplin toate cazurile. O mare parte a lucrului cu API-urile este să le citești documentația și să-ți dai seama ce vor de la tine.

Puncte de reflecție

Examinați întrebările și vedeți dacă știți răspunsurile. Verificați-vă din nou după finalizarea sarcinii.

  • Cum înțelege Rails ce tip de fișier așteptați ca răspuns când trimiteți o solicitare HTTP.
  • Care este scopul metodei #respond_to?
  • Cum returnați un obiect utilizator (Utilizator) în timp ce specificați atribute pe care nu doriți să le includă în acel obiect (adică nu puteți returna pur și simplu User.first)?
  • Numiți 2 pași în culisele metodei #to_json.
  • Cum îi spun unei acțiuni controlerului să redea doar un mesaj de eroare?
  • Cum să-ți creezi propriul mesaj de eroare?
  • De ce nu puteți utiliza metode de autentificare a controlerului bazate pe sesiune dacă doriți să permiteți conexiunea programatică la API-ul dvs.?
  • Ce este „Arhitectura Orientată pe Servicii”?

Bazele API

Aplicația dvs. Rails este de fapt deja un API, deși este posibil să nu vă gândiți la ea ca la un API. Browserul web lansat de utilizatorii dvs. este, de asemenea, un program, astfel încât de fapt trimite o solicitare API către aplicația dvs. Rails atunci când utilizatorul deschide o pagină nouă. Avem tendința de a gândi în acest fel, deoarece redarea șabloanelor HTML este o sarcină atât de comună, încât pur și simplu codificăm această funcționalitate în programele noastre de server ca tip de răspuns standard și considerăm că orice altceva este ceva neobișnuit.

Cu toate acestea, de multe ori doriți să faceți o solicitare care nu vă cere să treceți prin toate durerile de cap ale utilizării unui browser. Poate că nu vă pasă de structura paginii (HTML), dar în schimb doriți date curate. Să presupunem că doriți să obțineți o listă cu toți utilizatorii. Puteți solicita ceva de genul http://yourapplication.com/users , care probabil va declanșa acțiunea #index și va afișa o listă cu toți utilizatorii aplicației.

Dar de ce să te deranjezi cu toate aceste informații suplimentare când tot ce vrei este o listă de utilizatori? Cea mai simplă opțiune ar fi să trimiteți o solicitare la aceeași adresă URL, specificând în schimb așteptarea unui răspuns JSON sau XML. Dacă vă configurați corect controlerul Rails, veți primi înapoi un simplu obiect matrice JSON care conține toți utilizatorii. Minunat!

Același principiu se aplică atunci când comunicați cu un API extern. Să presupunem că doriți să obțineți „tweeturile” recente ale unui utilizator de pe Twitter. Tot ce trebuie să faceți este să spuneți aplicației dvs. Rails cum să interacționeze cu API-ul Twitter (adică să vă autentificați), să trimiteți cererea și să procesați setul de „tweeturi” care vor fi returnate.

Crearea unui API

Poate doriți să faceți din aplicația dvs. Rails un API back-end pur pentru paginile web front-end sau poate doriți pur și simplu să aflați cum să trimiteți JSON atunci când front-end-ul solicită acest lucru. Această secțiune nu va acoperi cum să creați API-uri RESTful complete cu funcționalitate de autentificare. Aceasta este o introducere simplă în tratarea aplicației dvs. ca API.

Bazele

Dacă doriți ca aplicația dvs. Rails să returneze JSON în loc de HTML, va trebui să spuneți controlerului dvs. să facă acest lucru. Lucrul grozav este că aceeași acțiune a controlerului poate returna tipuri diferite, în funcție de dacă utilizatorul face o solicitare normală de browser sau accesează un API prin linia de comandă. Aceasta determină ce tip de solicitare a fost făcută pe baza extensiei fișierului solicitat, cum ar fi example.xml sau example.json .

Puteți verifica ce „gândește” Rails despre tipul de fișier la care vă așteptați verificând jurnalul serverului:

A început GET „/posts/new” pentru 127.0.0.1 la 2013-12-02 15:21:08 -0800 Procesarea de către PostsController#new ca HTML

Prima linie vă spune ce adresă URL a fost solicitată, iar a doua vă spune unde a fost direcționată și cum o gestionează Rails. Dacă ar fi să utilizați extensia .json, ar arăta astfel:

A început GET „/posts.json” pentru 127.0.0.1 la 2013-12-04 12:02:01 -0800 Procesarea de către PostsController#index ca JSON

Dacă rulați o aplicație de testare, încercați să solicitați adrese URL diferite. Dacă controlerul tău nu știe cum să le gestioneze, atunci s-ar putea să primești o eroare, dar ar trebui totuși să poți vedea ce înțelege Rails prin solicitările tale.

Redare JSON sau XML

Când decideți că doriți să răspundeți cu JSON sau XML, va trebui să îi spuneți controlerului să redeze JSON sau XML în loc de HTML. O modalitate de a face acest lucru este să utilizați metoda #respond_to:

Clasa UsersController< ApplicationController def index @users = User.all respond_to do |format| format.html # index.html.erb format.xml { render xml: @users } format.json { render json: @users } end end end

În acest caz, #respond_to transmite un obiect format blocului la care puteți atașa apelul de randare corespunzător. Dacă nu faceți nimic, html va fi redat folosind șablonul standard Rails (app/views/index.html.erb în acest exemplu).

Funcția #render este suficient de inteligentă pentru a înțelege cum să redați o mare varietate de formate. Când îi transmiteți cheia:json , va apela #to_json pe valoarea, în acest exemplu @users . Aceasta va converti obiectele dvs. Ruby în șiruri JSON, care vor fi transmise aplicației solicitante.

Acesta este modul în care obțineți API-ul. Desigur, crearea unui API poate fi puțin mai complicată dacă doriți să faceți niște lucruri fanteziste, dar totul ține de elementele de bază.

Specificarea atributelor de returnare

Să presupunem că doriți să vă asigurați că nu returnați adresa de e-mail a unui utilizator împreună cu un obiect User. În acest caz, veți dori să modificați atributele care vor fi returnate, modificând ceea ce face metoda #to_json.

Anterior, tocmai ați fi suprascris metoda #to_json cu versiunea dvs., dar acum nu mai trebuie - de fapt, înlocuiți metoda #as_json. Metoda #as_json este folosită în metoda #to_json, deci modificarea acesteia schimbă implicit rezultatul #to_json , dar într-un mod destul de specific.

#to_json face 2 lucruri: rulează #as_json și primește un hash al atributelor care urmează să fie redate în JSON. Apoi se redă în JSON folosind ActiveSupport::json.encode . Deci, modificând #as_json , sunteți mai precis cu privire la partea din metoda #to_json pe care doriți să o modificați.

În cazul nostru, facem acest lucru modificând #as_json în modelul nostru pentru a returna numai atributele de care avem nevoie:

# app/models/user.rb clasa Utilizator< ActiveRecord::Base # Вариант 1: Полное переопределение метода #as_json def as_json(options={}) { :name =>self.name ) # NU includeți câmpul de e-mail end # Opțiunea 2: Folosiți metoda standard #as_json def as_json(options=()) super(only: [:name]) end end

Apoi, în controlerul nostru, tot ce trebuie să facem este să redăm JSON ca de obicei (exemplul de mai jos va returna întotdeauna JSON, indiferent dacă a fost trimisă sau nu o solicitare HTML):

# app/controllers/users_controller.rb clasa UsersController< ApplicationController def index render json: User.all end end

Rețineți că nu trebuie să apelați singur #to_json când utilizați #render - o va face pentru dvs.

Uneori, Heroku poate necesita pași suplimentari pentru a afișa corect paginile de eroare. Uite. Poate fi necesar să eliminați mai întâi paginile statice din aplicația/directorul public.

Asigurarea din exterior

Să presupunem că doriți să permiteți accesul la API numai dacă utilizatorul este conectat. Autentificarea controlerului dvs. existent deja face treaba - asigurați-vă doar că aveți setul corect #before_action (de exemplu, before_action:require_login). Este posibil să doriți o funcționalitate în care atât utilizatorii autentificați, cât și cei care nu sunt conectați pot vizualiza pagina, dar fiecare trebuie să vadă date diferite. Nu doriți ca utilizatorii neconectați să poată face solicitări API pentru a prelua date sensibile. De asemenea, nu doriți să permiteți utilizatorilor neautorizați să viziteze anumite pagini HTML.

Dacă doriți să procesați cereri de la o aplicație care nu este browser (de exemplu, din linia de comandă), nu vă puteți baza pe cookie-urile de browser pentru autentificare. Acesta este motivul pentru care majoritatea API-urilor folosesc token-uri native ca parte a procesului de autentificare. Vom vorbi mai mult despre jetoane în următoarea lecție.

Pasii urmatori

Acum aveți abilitățile de a vă folosi aplicația Rails pentru a servi nu doar HTML, ci și orice alt format. Dacă doriți să mergeți mai departe și să lăsați alți dezvoltatori să construiască lucruri folosind platforma dvs. (de exemplu, pentru a putea face cereri programatice în loc să se autentifice ca utilizator), va trebui să vă faceți sistemul API mult mai sigur. Nu vom acoperi totul aici, dar verificați următoarele:

  • Articolul Building Awesome Rails API-uri descrie multe dintre cele mai bune abordări pentru trecerea de la o aplicație de jucărie la API-uri standard din industrie.

Arhitectura orientată spre servicii

Este timpul să introducem o abordare arhitecturală numită Arhitectură Orientată către Servicii (SOA). Ideea de bază este că aplicația dvs. va consta din multe servicii, precum un sistem de plată, înregistrarea utilizatorilor, un modul de recomandare etc. În loc să construiți totul într-o aplicație principală, împărțiți subsistemele în bucăți complet independente care interacționează între ele folosind API-uri interne.

Acest lucru este bun din multe motive. Asigurându-vă că fiecărei părți a aplicației dvs. nu îi pasă cum funcționează celelalte părți și știe doar cum să solicite date prin intermediul API-ului lor, puteți face modificări semnificative codului de serviciu, iar restul aplicației va funcționa ca înainte. Puteți înlocui complet un serviciu cu altul și, atâta timp cât comunică folosind aceleași metode API, va funcționa foarte bine. Puteți utiliza API-uri externe ca parte a aplicației dvs. (cum ar fi procesatorii de plăți) în loc să le scrieți pe ale dvs. Puteți crea o aplicație PHP care interacționează cu o aplicație Python care interacționează cu o aplicație Rails și totul va funcționa, deoarece comunică între ei folosind API-ul.

În general, este o idee bună să încercați să păstrați fiecare parte a aplicației dvs. cât mai independentă posibil. Conceptul de SOA vă încurajează să vă gândiți exact în ceea ce privește metodele pe care doriți să le expuneți altor părți ale aplicației dvs. și, prin aceasta, vă va îmbunătăți codul. În plus, presupunând că fiecare componentă majoră a aplicației dvs. este independentă, puteți, de asemenea, să izolați problemele mult mai ușor și să gestionați erorile mai inteligent.

Utilizarea unei arhitecturi orientate către servicii pentru o întreagă aplicație este ca și cum a descompune un script Ruby uriaș și complex în clase și metode ingenioase, doar la scară mai mare.

Unul dintre cele mai cunoscute cazuri de tranziție la o arhitectură orientată spre servicii este Amazon.com. Într-o zi din 2002, Jeff Bezos a declarat fără îndoială că toate echipele de lucru trebuie să treacă la SOA sau să fie concediate. Notoriu postare pe blog un angajat Google, destinat în scopuri interne, dar expus accidental publicului, a vorbit despre puterea Amazon folosind SOA. Aceasta este o lectură grozavă, așa că asigurați-vă că o evaluați, dar principalele teze ale scrisorii lui Bezos sunt extrase din următoarele citate din postare:

1) Toate comenzile își oferă acum datele și funcționalitatea prin interfețe de serviciu.

2) Echipele trebuie să comunice între ele prin aceste interfețe.

3) Sunt interzise alte forme de comunicare între procese: fără legături directe, fără citire directă a datelor de la o altă comandă, fără modele de memorie partajată, fără „backdoors” și altele asemenea. Singura modalitate permisă de a comunica este accesarea interfeței de serviciu prin rețea.

4) Nu contează ce tehnologie folosesc. HTTP, Corba, Pubsub, protocoale native - nu contează. lui Bezos nu-i pasă.

5) Toate interfețele de service, fără excepție, trebuie să fie proiectate inițial cu capacitatea de a fi controlate din exterior. Adică, echipa trebuie să planifice și să proiecteze pentru a putea oferi o interfață dezvoltatorilor din afara companiei. Fara exceptii.

6) Oricine ignoră aceste cerințe va fi concediat.

SOA este o afacere serioasă. Sigur, există o mulțime de probleme care apar atunci când îl utilizați - consultați această postare pe „lecțiile învățate” Amazon - dar are o cantitate incredibilă de beneficii.

Probabil că nu vă veți face prea multe griji cu privire la SOA în timp ce construiți aplicații „de jucărie” pentru dvs., dar această întrebare va apărea cu siguranță când veți începe să lucrați pentru o companie IT, așa că este o bună practică să cunoașteți acest lucru.

Scopul tău

  1. Citiți Secțiunea 7 din Ghidul șinelor pentru controlere pentru a afla despre randarea JSON și XML.
  2. Nu sunt obligatorii vizionare (pentru că merg puțin mai departe decât avem în prezent), dar dacă sunteți interesat, aruncați o privire la Railscasts în secțiunea Resurse suplimentare din partea de jos a tutorialului pentru a afla mai multe despre beneficiile API.

Concluzie

Vom lucra mai îndeaproape cu aplicația dvs. ca API în timpul cursului Javascript. În acest curs, veți crea mai multe aplicații full-stack care utilizează apeluri AJAX pentru o experiență de utilizator mai bună, care implică de fapt redarea datelor XML sau JSON în loc de o pagină HTML completă. În continuare, veți crea mai multe aplicații Javascript cu o singură pagină care se bazează pe API-ul furnizat de aplicația Rails pentru a obține toate datele de care au nevoie din baza de date și, în caz contrar, vor rula pe partea client (în browser).

Cel mai bun mod de a face față unui API este să creați și să interacționați cu acesta, pe care ne vom concentra în proiectele noastre.

În această postare, am încercat să colectez informații care pot fi utile testerilor care doresc să știe ce este API-ul. Sper că oamenii cu experiență în testarea API vor găsi și ei ceva util pentru ei înșiși. Ei bine, sau măcar ajută la găsirea erorilor în articolul meu :)
Ce este API

API (Application Programming Interface) - un set de clase gata făcute, proceduri, funcții, structuri și constante furnizate de o aplicație (bibliotecă, serviciu) pentru utilizare în produse software externe (Wikipedia).

Cu alte cuvinte, API-ul ne oferă posibilitatea de a folosi dezvoltarea altor oameni în scopurile noastre. Pentru prima dată, am dat peste un API care folosește ca exemplu API-ul Windows. Acesta este un set de funcții pe care le poate folosi orice aplicație care rulează pe un anumit sistem de operare. De exemplu, poate folosi funcții standard pentru a desena interfața.

API-urile moderne iau adesea forma unor servicii web care oferă utilizatorilor (atât oameni, cât și alte servicii web) un fel de informații. De obicei, procedura de schimb de informații și formatul de transfer al datelor sunt structurate astfel încât ambele părți să știe cum să interacționeze între ele.

Pe site-ul https://dev.hh.ru/ (mai precis, https://github.com/hhru/api/blob/master/docs/general.md) puteți găsi o descriere a modului în care clienții API HeadHunter și serviciile interacționează între ele. De exemplu, un citat de pe site:

  • Toate API-urile funcționează prin protocolul HTTPS.
  • Autorizarea se realizează folosind protocolul OAuth2.
  • Toate datele sunt disponibile numai în format JSON.
  • Adresa URL de bază - https://api.hh.ru/
  • Datele sunt formatate conform ISO 8601: YYYY-LL-DDThh:mm:ss±hhmm
Puteți citi HH API - este un bun exemplu de documentație pentru utilizator.

Formate de transfer de date

Există multe formate de date pe care utilizatorii le folosesc pentru a interacționa cu API-ul. De exemplu, binecunoscutul XML. Sau JSON - un format ușor și necomplicat, care arată astfel:

( „id”: „0001”, „tip”: „goasă”, „nume”: „Prăjitură”, „imagine”: ( „url”: „imagini/0001.jpg”, „lățime”: 200, „înălțime” „: 200)) P despre ss În linkurile de mai jos puteți vedea răspunsurile care vin de la MediaWikiAPI , în diferite formate :

JSON:https://en.wikipedia.org/w/api.php?action=query&titles=Albert%20Einstein&prop=info&format=jsonfm
XML: https://en.wikipedia.org/w/api.php?action=query&titles=Albert%20Einstein&prop=info&format=xmlfm
PHP: https://en.wikipedia.org/w/api.php?action=query&titles=Albert%20Einstein&prop=info&format=php ( cu grija, întâmpla cu legănat fişier)

http g lagos

De obicei P Când accesați API-ul webfolosind Solicitările HTTP sunt trimise . De aceeacel putin pe scurt despre metode standard, care poate fi cuprins în Solicitare HTTP . Aceste metode numite și verbe HTTP :

  • OBȚINE. Probabil cel mai popular tip cerere. Folosit pentru a primi sau a citi date.
  • A PUNE. Ca de obicei n Oh si spo Folosit pentru a actualiza o resursă .
  • POST. Folosit de obicei pentru a crea o resursă nouă.
  • ȘTERGE. Șterge datele.
  • Si altii
Dacă vrem să obținem informații despre o resursă,al cărui URI http://www.example.com/customers/12345 , putem trimite o cerere:
GET http://www.example.com/customers/12345

Dacă vrem să actualizăm o resursă - putem trimite o cerere PUT:
PUT http://www.example.com/customers/12345/orders/98765

Solicitările GET normale pot fi trimise printr-un browser web. Trimiterea altor tipuri de solicitări poate necesita limbaje de scripting sau instrumente speciale (mai multe despre acestea mai jos).

Despre HTTP metodele pot fi citite mai detaliat la pe W iki.

HTTP la oda răspunsurilor

Serverul poate trimite diferite coduri ca răspuns la solicitările utilizatorilor. Acestea pot fi coduri de eroare sau pur și simplu coduri care informează utilizatorii despre starea serverului. O descriere detaliată poate fi găsită, din nou, pe wiki.

Cele mai cunoscute coduri sunt 4xx (probleme la nivelul clientului) și 5xx (probleme la nivelul serverului). Dezvoltatorii API-ului înșiși decid ce coduri să returneze într-o anumită situație. De exemplu, API-ul site-ului Odnoklassniki returnează coduri, a căror descriere poate fi găsită pe pagina https://apiok.ru/wiki/pages/viewpage.action?pageId=77824003 .

În plus, vă sfătuiesc să ascultați cântecul Request-response - simplu și clar despre codurile returnate în cererile HTTP (atenție, repchik :)).


API-ul REST

REST API - aceasta este ideologia postării roire API, care înseamnăTransfer de stat reprezentativ API. Se bazează pe următoarele principii formulate de creatorul său , Roy Fielding:

  1. Arhitectura client-server
  2. Server apatrid
  3. cachebilitatea
  4. Structura multistrat
  5. Interfață unică
  6. Cod la cerere
Nu intru in detalii, pot sfatui pe cei care doresc sa citeasca pe tema

Top articole similare