Nasljeđivanje Delphi interfejsa. Karakteristike rada sa interfejsima u Delphiju

Imam problem sa korištenjem Delphi klase iz C++ koda. delphi dll demo koji izvozi funkciju koja vraća objekat.
moj Delphi Dll kod izgleda ovako:

Library DelphiTest; // koristi dio .... tip IMyObject = procedura interfejsa DoThis (n: Integer); funkcija DoThat: PWideChar; kraj; TMyObject = klasa (TInterfacedObject, IMyObject) procedura DoThis (n: Integer); funkcija DoThat: PChar; kraj; // Implementacija TMyObject idi ovdje ... procedura TMyObject.DoThis (n: Integer); begin showmessage ("pozivate DoThis metodu sa" + intToStr (n) + "parametar"); kraj; funkcija TMyObject.DoThat: PChar; započeti showmessage ("pozivate DoThat funkciju"); Rezultat: = Pchar ("Hello im Dothat"); kraj;

// izvoz DLL funkcije:

Funkcija CreateMyObject: IMyObject; stdcall;export; var txt: TextFile; započeti AssignFile (txt, "C: \ log.log"); Resetuj (txt); Writeln (txt, "zdravo"); Rezultat: = TMyObject.Create; kraj; izvozi CreateMyObject;

u svom C++ projektu deklarirao sam IMyObject sučelje ovako:

Klasa IMyObject (javno: IMyObject (); virtual ~ IMyObject (); virtual void DoThis (int n) = 0; virtual char * DoThat () = 0;);

a moja glavna funkcija je ovakva:

Typedef IMyObject * (__stdcall * CreateFn) (); int main () (HMODULE hLib; hLib = LoadLibrary (L "DelphiTest.dll"); assert (hLib! = NULL); // pass !! CreateFn pfnCreate; pfnCreate = (CreateFn) GetProcAddress ((HINSTANCE) hLibObject, " "); if (pfnCreate == NULL) (DWORD errc = GetLastError (); printf ("% u \ n ", errc); // dobiva grešku 127) else (printf (" uspješno učitavanje \ n ");) IMyObject * objptr = pfnCreate (); objptr-> Uradi ovo (5); FreeLibrary (hLib); int in; scanf_s ("% i", & in); vrati 0;)

u ovom primjeru, dobio sam runtime error kada pokušam pristupiti izvezenoj funkciji. greške u liniji:
IMyObject * objptr = pfnCreate ();

Možete li mi reći šta nije u redu sa mojim primjerom.
i ako je moguće bilo koji radni primjer za pristup Delphi klasi (u DLL-u) iz C++ koda.

Rješenje

Prvi problem je pozivanje konvencije metoda. Delphi interfejs koristi registar koji je posebna konvencija o pozivanju za Delphi. koristeći stdcall Na primjer, za metode interfejsa.

Sljedeći problem je u C++. Vaše C++ sučelje mora biti izvedeno iz IUnknown-a. Također, ne smije deklarirati konstruktor ili destruktor.

Osim toga, vaš Delphi kod izvozi PWideChar koji se ne mapira u char *, već se mapira u wchar_t *.

Gledajući dalje, vraćanje PChara ovdje odlično funkcionira jer vaša implementacija vraća literal. Ali ozbiljniji kod će vjerovatno htjeti koristiti dinamički dodijeljeni niz, u tom trenutku vaš dizajn je pogrešan.

Imajte na umu da morate biti povišeni administrator da biste kreirali datoteku u korijenu sistemskog diska. Dakle, ovo je još jedna potencijalna tačka neuspjeha.

Očekujem da ima i drugih grešaka, ali ovo je sve što sam do sada našao.

Članak je napisan na osnovu rezultata analize programa koje su napisali mladi programeri naše grupe.

Pravilno rasporedite redoslijed sklopnih komponenti

Mnogi korisnici, posebno oni koji su ranije radili u DOS-u, imaju naviku da prelaze između polja za unos ne pomoću miša, već pomoću tastature pomoću tastera Tab. Osim toga, to je mnogo brže od odabira svakog polja mišem. Stoga, redoslijed prebacivanja komponenti mora biti ispravno postavljen. Ovo se odnosi i na komponente unutar svih komponenti kontejnera (paneli, GroupBoxovi i slično), i na same komponente kontejnera, ako ih ima nekoliko na obrascu.

Redoslijed prebacivanja komponenti unutar kontejnera je postavljen svojstvom TabOrder. Prva postaje aktivna komponenta, u kojoj je TabOrder 0, druga sa 1, i tako dalje, sve dok se sve komponente ne nabroje. Osim toga, komponenta ima svojstvo TabStop koje ukazuje da li će komponenta dobiti fokus kada se prebaci pomoću tipke Tab. Ako trebate zabraniti prelazak na bilo koju komponentu, postavite njen TabStop = false. U ovom slučaju, možete se prebaciti na ovu komponentu samo pomoću miša.

Postoje slučajevi kada korisnici koji su navikli mijenjati određeni ključ u jednom programu, iz navike ga i dalje koriste u ostalima. To se često događa kod korisnika 1C, gdje se tipka Enter može koristiti za navigaciju kroz polja za unos. Pa, dajmo im ovu priliku u našim programima, ako to traže. Postavite svojstvo KeyPreview obrasca na true i napišite obrađivač događaja za događaj OnKeyPress:

Procedura TForm1.FormKeyPress (Pošiljalac: TObject; var ključ: Char);
početi
ako je ord (ključ) = vk_Return onda
Form1.SelectNext (PriemForm.ActiveControl, true, true);
kraj;

Takav rukovalac omogućava navigaciju kroz elemente obrasca kada se pritisne tipka Enter. Treba napomenuti da ova metoda neće raditi sa dugmadima, jer pritiskom na Enter na dugme se ono pritisne, dok pritiskom na Tab prenosi fokus ulaza na sledeću komponentu u nizu za prebacivanje.

Podrazumevana dugmad

Isti se korisnici brzo naviknu na činjenicu da u dijaloškim okvirima aplikacije u pravilu svoj izbor možete potvrditi tipkom Enter, a otkazati tipkom Esc. Nemojmo ih razočarati u našim programima, pogotovo što je to vrlo lako učiniti. Za dugme koje odgovara na Enter, postavite svojstvo Default na true. Za dugme koje odgovara na Esc, postavite svojstvo Cancel na true. I to je sve.

da ili ne

Svi dijaloški okviri koji zahtijevaju radnje korisnika moraju imati najmanje dva gumba: potvrditi radnju i otkazati radnju (Da / Ne, Sačuvaj / Otkaži, itd.). Radnja se može otkazati zatvaranjem prozora sa dugmetom [X] u naslovu prozora. Neprihvatljivo je ako postoji samo jedno dugme za potvrdu radnje, a za odbijanje treba zatvoriti prozor sa dugmetom [X] u zaglavlju, ili uopšte ne postoji mogućnost odbijanja. Ovo zbunjuje korisnika, postavljajući logično pitanje: kako odbiti?

Također, ne zaboravite na ono što je gore rečeno u odjeljku "Podrazumevana dugmad".

Svi dijaloški okviri bi se trebali otvoriti u sredini ekrana

Centrirano, a ne tamo gdje su kreirani u dizajnu. Prvo, jasnije je, a drugo, automatski eliminiše problem različitih rezolucija ekrana za različite korisnike.

Izuzetak se pravi ako dijaloški okvir nije modalan, a kao rezultat rada korisnika, u ovom prozoru se odmah javljaju promjene u glavnom prozoru (na primjer, filtriranje skupa podataka, ponovno iscrtavanje grafikona, itd.).

Windows ne smije biti veći od ekrana

Ni u kom slučaju. Sramota je kada dio prozora ispuzi iz ekrana. Ovaj zahtjev ne ovisi o rezoluciji ekrana korisnika, tj. izgovori poput "Neka dobiju više dozvole" ne funkcioniraju.

Ispravno mijenjanje veličine elemenata prozora

Elementi prozora moraju promijeniti veličinu ili se pravilno pomicati kada se promijeni veličina prozora, kada je prozor maksimiziran i kada se prozor vrati nakon maksimiziranja.

Sve je uvek vidljivo

Smanjenje veličine prozora ne bi trebalo da dovede do nestanka elemenata prozora i, po mogućnosti, ne bi trebalo da dovede do pojave klizača (skrolera) samog prozora. Možete ograničiti minimalnu veličinu prozora tako da svi elementi budu vidljivi i dostupni. Ako nije moguće postaviti komponente na takav način da su sve vidljive u prozoru, možete koristiti kartice (kao što je PageControl) da podijelite komponente u grupe. Također ne propuštamo izgovore o rezoluciji ekrana.

Nagoveštaji svuda, saveti uvek

Za dugmad, posebno na trakama sa alatkama (kao što je Toolbar), nagoveštaje treba postaviti tako da uvek bude jasno zašto je potrebno ovo ili ono dugme.

Spektar boja

Ne bojite komponente na formu svim duginim bojama. Ovo zamara oči i odvlači pažnju korisnika. Ne izgleda kul. Isticanje se koristi kada je potrebno skrenuti pažnju korisnika na određeni element ili određeni dio prozora. Na primjer, boje zapise svijetlocrvene boje, koji sadrže greške, ili, obrnuto, svijetlo zelene boje za zapise koji su uspješno provjereni.

Zaključak

Postoji vrlo dobra metoda koja vam omogućava da pronađete nedostatke programa općenito, a posebno sučelja. Jednostavno je: zamislite sebe na korisnikovom mjestu i pola sata pokušajte raditi kako funkcionira. Još je bolje ako je vaš korisnik na dohvat ruke (na primjer, radi u istoj organizaciji). U ovom slučaju, sedite pored njega, odnosno umesto njega, i pokušajte da mu uspete. Unesite podatke, promijenite ih, prikažite izvještaje itd. Ako ne znate kako to učiniti kako treba, pitajte svog korisnika. Nemojte izvršiti jednu ili dvije operacije istog tipa, kao u načinu za otklanjanje grešaka, već 20-30, ili čak više, različitih operacija, različitim redoslijedom. Zaboravite nešto da unesete ili unesete pogrešno i pogledajte kako program reaguje na to. Brzo ćete uočiti slabosti vašeg programa.

Autor članka je automatizirao rad prijemne kancelarije na fakultetu, te je prve godine uvođenja programa provodio 3-4 sata dnevno na prijemnoj kancelariji, registrovao kandidate, popunjavao njihove lične podatke i dajući im izvještaje sa ispita. I u preostalom radnom vremenu ispravljao je greške i nedostatke. Vjerujte, sljedeće godine praktično više nema problema. Tako je bilo i sa uvođenjem kadrovskog modula.

Stoga, imajte na umu korisničko iskustvo. Učinite im lakim i ugodnim rad s vašim programima.

Ovaj članak je zasnovan na pitanjima na forumima: "Kako mogu da vratim string iz DLL-a?", "Kako prenijeti i vratiti niz zapisa?", "Kako prenijeti obrazac u DLL?"

Kako ne biste potrošili pola života pokušavajući to shvatiti, u ovom članku ću sve iznijeti na srebrnom tacnu.

Teme ovog članka su već dotaknute na ovom blogu u različitom stepenu, ali u ovom članku su skupljene u gomilu, dato je obrazloženje. Ukratko, veza do ovog članka može se baciti onima koji razvijaju DLL-ove.

Važna napomena: članak treba pročitati dosljedno... Primjeri kodova su dati samo kao primjeri, na svakom koraku (paragrafu) članka dodaje se šifra primjera s novim detaljima. Na primjer, na samom početku članka nema rukovanja greškama, naznačene su "klasične" metode (kao što su korištenje GetLastError, sdtcall konvencije itd.), koje se u toku članka zamjenjuju adekvatnijim. To se radi iz razloga što "nove" ("neobične") konstrukcije ne izazivaju pitanja. U suprotnom, za svaki primjer, morali biste umetnuti napomenu u obliku: "o ovome se govori u tom paragrafu ispod, ali o ovome u ovom." U svakom slučaju, na kraju članka nalazi se link na gotov kod, napisan uzimajući u obzir sve što je rečeno u članku. Možete ga jednostavno uzeti i koristiti. A članak objašnjava zašto i zašto. Ako vas ne zanima "zašto i zašto" - skrolujte do zaključka i linka za preuzimanje primjera.

samo za rezultat

striktno poštovanje rokova

Transparentnost

izvođenje projekta

tehnička podrška na poklon

Programiranje, revizija savjeta na 1C

Kako radimo

1. Razgovaramo o problemu preko telefona. Ako imate daljinski pristup, prikažite ga na ekranu računara.

2. Rad procjenjujemo u rubljama, ako je projekat velik, ako ne - približan broj sati.

3. Završili smo posao.

4. Vi prihvatate rad u svom programu, ako postoje nedostaci, mi ih ispravljamo.

5. Mi izdajemo fakturu, vi plaćate.

Troškovi rada

1. Sav posao je podijeljen u 3 kategorije: konsultacije, ažuriranje tipične konfiguracije, razvoj ili programiranje novog izvještaja, obrada, dugmad, itd.

3. Za rad duži od 10 sati prethodno se izrađuje tehnički zadatak sa opisom i cijenom radova. Rad počinje nakon usaglašavanja projektnog zadatka sa vama.

Tehnička podrška

1. Ukoliko pronađete greške u prethodno prihvaćenim radovima, u roku od 3 mjeseca, ispravljamo ih besplatno.

2. Za stalne kupce sve nedostatke u radu ispravljamo besplatno tokom cijele godine.

Programi za upravljanje vašim poslovanjem.

Kupite 1C: Enterprise

Mi smo službeni zastupnik 1C, od nas možete kupiti razne softverske proizvode i licence. Osim kupovine "kutije", pomoći ćemo vam da postavite program, savjetujemo i izvršite osnovna podešavanja.

  • Računovodstvo
  • Automatizacija prodavnice
  • Veleprodaja
  • Pomoć za instalaciju i početno podešavanje je uključena u paket!
  • Fino podešavanje konfiguracija za potrebe kupca, razvoj novih modula u nedostatku potrebnih funkcija u standardnoj konfiguraciji.
1c računovodstvo 1C: Upravljanje trgovinom 1C: Maloprodaja 1C: Plaća i upravljanje osobljem
Od 3300 rub. Od 6700 rub. Od 3300 rub. Od 7400 rub.

Omogućavanje servera.

Server za trenutno podešavanje + 1C.

Nemate server? Nema veze, mi ćemo preuzeti i brzo postaviti server u "oblaku". Za malu naknadu dobijate veoma pouzdano rešenje.

  • Dostupnost 24/7
  • Nema potrebe da zadržite sopstvenog sysadmina (uštede će pokriti troškove vašeg servera).
  • Brzo podešavanje i instalacija 1C na serveru, za 3 dana ćete već imati potpuno ispravan sistem.
  • U svakom trenutku možete preći na lokalni server ako vam rješenje ne odgovara.

SMS sa vašeg 1C

Želite da kupci na vrijeme znaju za promocije, popuste? Kupci se ne vraćaju? Podesite slanje SMS-a direktno iz 1C!

Naša kompanija će moći brzo podesiti slanje SMS-a vašim klijentima direktno iz 1C. Primjeri događaja koji se mogu automatizirati:

  • Hvala na kupovini i prikupljanju bonusa odmah nakon sljedeće kupovine.
  • Prikupljanje bonusa na karticu kao poklon za rođendan \ za drugi značajan ili praznik.
  • Obavijest o prispijeću robe u skladište.
  • Istek poklon bonusa.
  • Obaveštenje o prijemu avansa i rezervaciji robe.
  • Adresa sa detaljima kako doći do prodavnice/kancelarije, brojevima telefona.
  • itd.

Postavke u 1C mogu izvršiti naši stručnjaci ili naši zaposlenici. Sa tarifama se možete upoznati na stranici SMS tarife.

  • Garancija dostave SMS-a, novac se podiže samo za isporučeni SMS.
  • Zasebna naplata za svaki SMS.
  • Dopuna bilansa na različite načine.
  • Pogledajte historiju svih poslanih SMS-a u bilo kojem trenutku.
  • Ime pošiljaoca umjesto digitalnog broja na telefonu primaoca poruke.

Objektno orijentisano programiranje (OOP), pored koncepta klase, takođe obezbeđuje osnovni koncept interfejsa.

Šta je interfejs i koje su karakteristike rada sa njim u programskom jeziku Delphi?

Interfejs je semantička i sintaktička konstrukcija u programskom kodu koja se koristi za specifikaciju usluga koje pruža klasa ili komponenta (Vikipedija).

U stvari, interfejs definiše listu svojstava i metoda koje treba koristiti pri radu sa klasom koja implementira ovaj interfejs, kao i njihov potpis (ime, tip podataka, prihvaćeni parametri (za procedure i funkcije) itd.). Dakle, klasa koja implementira određeni interfejs mora nužno implementirati sve svoje komponente. Štaviše, u strogom skladu sa načinom na koji su u njemu opisani.

Interfejsi se često porede sa apstraktnim klasama, ali uprkos sličnosti, ovo poređenje nije sasvim ispravno. U apstraktnim klasama je dostupna barem kontrola nad vidljivošću članova. Istovremeno, za interfejse nisu definisani opseg.

Interfejsi vam omogućavaju da arhitekturu učinite fleksibilnijom, jer objedinjuju pristup jednoj ili drugoj funkcionalnosti, a također vam omogućavaju da izbjegnete niz problema povezanih sa nasljeđivanjem klasa (sučelja se također mogu naslijediti jedan od drugog).

Da biste deklarirali interfejs u Delphiju, koristite ključnu riječ interfejs. Ovo je ista ključna riječ koja definira dio jedinice kojem se može pristupiti izvana (između ključnih riječi interfejs i implementacija). Međutim, kada se deklariše interfejs, koristi se drugačija sintaksa, slična deklaracijama klase.

Delphi / Pascal

IMyNewInterface = procedura interfejsa InterfaceProc; kraj;

IMyNewInterface = interfejs

procedure InterfaceProc;

kraj;

Dakle, sama sintaksa deklaracije interfejsa se suštinski ne razlikuje od drugih programskih jezika (osobine sintakse zasnovane na Pascalu se ne računaju). Istovremeno, implementacija interfejsa ima niz karakterističnih karakteristika.

Poenta je da su Delphi interfejsi prvobitno uvedeni da podržavaju COM tehnologiju. Dakle, interfejs IIinterface, koji je u Delphiju predak svih ostalih interfejsa (neka vrsta analoga TObject), već sadrži tri osnovne metode za rad sa ovom tehnologijom: QueryInterface, _AddRef, _Release. Kao rezultat toga, ako klasa implementira bilo koji interfejs, onda mora bez greške implementirati ove metode. Čak i ako ova klasa nije dizajnirana za rad sa COM.

Zbog ove karakteristike interfejsa IIinterface, u Delphiju, upotreba interfejsa, u većini slučajeva, dovodi do dodavanja namerno neiskorišćenih mogućnosti u klasu.

Postoji bibliotečka klasa TInterfaceObject koja već sadrži implementaciju ovih metoda i, kada se od nje nasljeđuje, nema potrebe da ih sami implementirate. Ali pošto Delphi ne podržava višestruko nasljeđivanje klasa, njegova upotreba često samo uzrokuje dodatne poteškoće u dizajnu i implementaciji već potrebne funkcionalnosti.

Sve je to dovelo do činjenice da, uprkos svim mogućnostima koje pružaju interfejsi, njihova praktična upotreba u Delphiju gotovo da nije išla dalje od rada sa COM-om.

Optimizirani za rad prvenstveno sa ovom tehnologijom, interfejsi, odnosno funkcionalna i arhitektonska ograničenja koja dodaju na obaveznoj osnovi, ne opravdavaju se pri rješavanju drugih problema.

Stoga su mnogi Delphi programeri još uvijek, zapravo, lišeni moćnog i fleksibilnog alata za razvoj arhitekture aplikacija.

Podijelite ovo