Delphi interfész öröklődése. A Delphi interfészeivel való munka jellemzői

Problémám van a Delphi osztály használatával a C ++ kódból. delphi dll demó, amely egy objektumot visszaadó függvényt exportál.
a Delphi Dll kódom így néz ki:

Könyvtár DelphiTest; // ... részt használ. type IMyObject = interfész eljárás DoThis (n: Integer); Funkció DoThat: PWideChar; vége; TMyObject = osztály (TInterfacedObject, IMyObject) eljárás DoThis (n: Integer); funkció DoThat: PChar; vége; // TMyObject implementáció megy ide ... procedúra TMyObject.DoThis (n: Integer); begin showmessage ("a DoThis metódust a következővel hívod meg" + intToStr (n) + "paraméter"); vége; függvény TMyObject.DoThat: PChar; start showmessage ("a DoThat függvényt hívod"); Eredmény: = Pchar ("Hello im Dothat"); vége;

// exportálja a DLL függvényt:

Funkció CreateMyObject: IMyObject; stdcall, export; var txt: TextFile; begin AssignFile (txt, "C: \ log.log"); Reset (txt); Writeln (txt, "hello"); Eredmény: = TMyObject.Create; vége; exportálja a CreateMyObjectet;

a C ++ projektemben így deklaráltam az IMyObject felületet:

IMyObject osztály (nyilvános: IMyObject (); virtual ~ IMyObject (); virtuális void DoThis (int n) = 0; virtuális karakter * DoThat () = 0;);

és a fő funkcióm a következő:

Typedef IMyObject * (__stdcall * CreateFn) (); int main () (HMODULE hLib; hLib = LoadLibrary (L "DelphiTest.dll"); assert (hLib! = NULL); // pass !! CreateFn pfnCreate; pfnCreate = (CreateFn) GetProcAddress ((HINSTANCE) hLib, "CjectCreateMy" "); if (pfnCreate == NULL) (DWORD errc = GetLastError (); printf ("% u \ n ", errc); // 127-es hibát kap) else (printf (" sikeres betöltés \ n ");) IMyObject * objptr = pfnCreate (); objptr-> DoThis (5); FreeLibrary (hLib); int in; scanf_s ("% i", & in); return 0;)

ebben a példában futásidejű hibát kaptam, amikor megpróbáltam elérni az exportált függvényt. hibák a sorban:
IMyObject * objptr = pfnCreate ();

Meg tudná mondani, mi a baj a példámmal?
és ha lehetséges, bármilyen működő példa Delphi osztály eléréséhez (DLL-ben) C ++ kódból.

Megoldás

Az első probléma a módszerek konvenciójának elhívása. A Delphi interfész regisztert használ, amely egy Delphi-specifikus hívási konvenció. stdcall használatával Például interfész metódusokhoz.

A következő probléma a C ++-ban van. A C ++ interfésznek az IUnknown-ból kell származnia, továbbá nem deklarálhat konstruktort vagy destruktort.

Ezen kívül a Delphi-kódot a PWideChar exportálja, amely nem char *-ra, hanem wchar_t *-ra van leképezve.

Ha tovább nézünk, a PChar visszaadása itt remekül működik, mert a megvalósítás egy literált ad vissza. De a komolyabb kód valószínűleg dinamikusan lefoglalt karakterláncot szeretne használni, ekkor a tervezés hibás.

Kérjük, vegye figyelembe, hogy felsőfokú rendszergazdának kell lennie ahhoz, hogy fájlt tudjon létrehozni a rendszermeghajtó gyökerében. Tehát ez egy újabb lehetséges kudarcpont.

Remélem vannak más hibák is, de eddig csak ezt találtam.

A cikk a csoportunk fiatal fejlesztői által írt programok elemzésének eredményei alapján készült.

Helyesen rendezze el az alkatrészek kapcsolási sorrendjét

Sok felhasználónak, különösen azoknak, akik korábban DOS-ban dolgoztak, megvan a szokásuk, hogy nem az egérrel váltanak a beviteli mezők között, hanem a billentyűzetet a Tab billentyűvel használják. Ráadásul sokkal gyorsabb, mint az egyes mezők egérrel történő kijelölése. Ezért az alkatrészek kapcsolási sorrendjét helyesen kell beállítani. Ez vonatkozik mind az összes konténer-összetevőn belüli komponensekre (panelek, GroupBoxok és hasonlók), mind magukra a konténer-összetevőkre, ha több is van belőlük az űrlapon.

A tárolón belüli összetevők váltási sorrendjét a TabOrder tulajdonság határozza meg. Az első lesz az aktív komponens, amelyben a TabOrder értéke 0, a második 1-gyel, és így tovább, amíg az összes összetevőt fel nem sorolják. Ezenkívül az összetevő rendelkezik egy TabStop tulajdonsággal, amely jelzi, hogy az összetevő fókuszba kerül-e, ha a Tab billentyűvel vált. Ha meg kell tiltania a váltást bármely összetevőre, állítsa be a TabStop = false értéket. Ebben az esetben erre az összetevőre csak az egér segítségével lehet váltani.

Vannak esetek, amikor azok a felhasználók, akik hozzászoktak ahhoz, hogy megszokásból váltsanak egy bizonyos kulcsot egy programban, a többiben továbbra is használják. Ez gyakran előfordul az 1C felhasználóknál, ahol az Enter billentyűvel lehet navigálni a beviteli mezők között. Nos, adjuk meg nekik ezt a lehetőséget a programjainkban, ha kérik. Állítsa az űrlap KeyPreview tulajdonságát true értékre, és írjon eseménykezelőt az OnKeyPress eseményhez:

Eljárás TForm1.FormKeyPress (Sender: TObject; var Key: Char);
kezdődik
if ord (kulcs) = vk_Return akkor
Form1.SelectNext (PriemForm.ActiveControl, igaz, igaz);
vége;

Egy ilyen kezelő navigációt biztosít az űrlapelemek között az Enter billentyű lenyomásakor. Meg kell jegyezni, hogy ez a módszer nem működik gombokkal, mivel az Enter megnyomásával a gomb megnyomására kerül sor, míg a Tab megnyomásával a bemeneti fókusz a váltási sorrend következő összetevőjére kerül.

Alapértelmezett gombok

Ugyanazok a felhasználók gyorsan megszokják, hogy az alkalmazások párbeszédpaneleiben általában az Enter billentyűvel erősítheti meg a választását, és az Esc billentyűvel törölheti. Ne okozzunk nekik csalódást programjainkban, főleg, hogy ezt nagyon könnyű megtenni. Az Enterre reagáló gomb esetén állítsa az Alapértelmezett tulajdonságot igaz értékre. Az Esc-re reagáló gombnál állítsa a Mégse tulajdonságot true értékre. És ennyi.

igen vagy nem

Minden felhasználói műveleteket kérő párbeszédpanelen legalább két gombnak kell lennie: a művelet megerősítése és a művelet megszakítása (Igen / Nem, Mentés / Mégse stb.). Egy művelet megszakítható az ablak bezárásával az ablak címében található [X] gombbal. Elfogadhatatlan, ha csak egy gomb van a művelet megerősítésére, és az elutasítás az ablakot bezárja a fejlécben található [X] gombbal, vagy egyáltalán nincs visszautasítási lehetőség. Ez megzavarja a felhasználót, és felveti a logikus kérdést: hogyan utasítsa el?

Ne feledkezzünk meg arról sem, amit fentebb az „Alapértelmezett gombok” részben mondtak.

Minden párbeszédpanelnek meg kell nyílnia a képernyő közepén

Középre helyezve, nem oda, ahol tervezési módban létrehozták. Egyrészt világosabb, másrészt automatikusan kiküszöböli a különböző képernyőfelbontások problémáját a különböző felhasználók számára.

Kivételt képez, ha a párbeszédablak nem modális, és a felhasználó munkájának eredményeként ebben az ablakban azonnal bekövetkeznek a főablak változásai (például adathalmaz szűrése, grafikonok átrajzolása stb.).

Az ablakok nem lehetnek nagyobbak, mint a képernyő

Semmilyen esetben sem. Szégyen, ha az ablak egy része kimászik a képernyőn. Ez a követelmény nem függ a felhasználó képernyőfelbontásától, pl. az olyan kifogások, mint a "Kérjenek több engedélyt" nem működnek.

Az ablakelemek helyes átméretezése

Az ablakelemeknek megfelelően át kell méretezni vagy el kell mozogni az ablak átméretezésekor, ha az ablakot maximalizáljuk, és amikor az ablakot a nagyítás után visszaállítjuk.

Mindig minden látható

Az ablak méretének csökkentése nem vezethet az ablakelemek eltűnéséhez, és lehetőleg nem vezethet görgetősávok (görgető) megjelenéséhez az ablakon. Korlátozhatja az ablak minimális méretét, hogy minden elem látható és hozzáférhető legyen. Ha nem lehetséges úgy elhelyezni a komponenseket, hogy az összes látható legyen az ablakban, akkor a tabulátorok (például a PageControl) segítségével csoportokra oszthatja az összetevőket. A képernyőfelbontással kapcsolatos kifogásokat sem hagyjuk ki.

Tanácsok mindenhol, tippek mindig

A gombokhoz, különösen az eszköztárakon (például az Eszköztáron) célszerű tippeket beállítani, hogy mindig világos legyen, miért van szükség erre vagy arra a gombra.

Színspektrum

Ne fesse le az űrlap alkatrészeit a szivárvány összes színére. Ez fárasztja a szemet, és elvonja a felhasználó figyelmét. Nem néz ki menőnek. A kiemelést akkor használjuk, ha fel kell hívni a felhasználó figyelmét az ablak egy bizonyos elemére vagy egy bizonyos részére. Például színezheti a rekordokat világospiros színűre, amelyek hibákat tartalmaznak, vagy fordítva, világoszöld színűre a sikeresen ellenőrzött rekordokat.

Következtetés

Van egy nagyon jó módszer, amely lehetővé teszi általában a program és különösen az interfész hiányosságainak megtalálását. Egyszerű: képzeld magad a felhasználó helyébe, és fél órán keresztül próbálj úgy dolgozni, ahogy működik. Még jobb, ha a felhasználó elérhető közelségben van (például ugyanabban a szervezetben dolgozik). Ebben az esetben ülj mellé, vagy inkább helyette, és próbáld meg a dolgát. Adatok bevitele, módosítása, jelentések megjelenítése stb. Ha nem tudja, hogyan kell helyesen csinálni, kérdezze meg felhasználóját. Ne egy vagy két azonos típusú műveletet végezzen, mint a hibakeresési módban, hanem 20-30, vagy akár több különböző műveletet, eltérő sorrendben. Ne felejtsen el beírni valamit, vagy hibásan írja be, és nézze meg, hogyan reagál rá a program. Gyorsan látni fogja a program gyengeségeit.

A cikk írója automatizálta a felvételi iroda munkáját az egyetemen, és a program bevezetésének első évében napi 3-4 órát töltött a felvételi irodában, regisztrálta a jelentkezőket, kitöltötte személyes adatait, ill. vizsgajelentéseket adva nekik. A hátralévő munkaidőben pedig kijavította a hibákat, hiányosságokat. Higgye el, jövőre gyakorlatilag nem marad semmi probléma. Így volt ez a személyi modul bevezetésével is.

Ezért tartsa szem előtt a felhasználói élményt. Tedd egyszerűvé és kellemessé számukra a programokkal való munkát.

Ez a cikk a fórumon feltett kérdéseken alapul: "Hogyan tudok visszaadni egy karakterláncot egy DLL-ből?", "Hogyan lehet rekordtömböt átvinni és visszaküldeni?", "Hogyan vihetünk át egy űrlapot DLL-be?"

Hogy ne vesztegesd a fél életedet azzal, hogy kitaláld, ebben a cikkben mindent egy ezüsttálcán viszek fel.

A cikk témáival már ebben a blogban is foglalkoztunk különböző mértékben, de ebben a cikkben ezeket egy csokorba gyűjtöttük, az indoklást megadjuk. Röviden, egy linket erre a cikkre lehet dobni azoknak, akik DLL-eket fejlesztenek.

Fontos jegyzet: a cikket el kell olvasni következetesen... A kódpéldák csak mint példák, a cikk minden lépésénél (bekezdésénél) a példák kódja új részletekkel egészül ki. Például a cikk legelején nincs hibakezelés, a "klasszikus" metódusok (például GetLastError használata, sdtcall konvenciók stb.) vannak feltüntetve, amelyeket a cikk során megfelelőbbekre cserélnek. Ez azért van így, mert az "új" ("szokatlan") konstrukciók nem vetnek fel kérdéseket. Ellenkező esetben minden egyes példához be kell illesztenie egy megjegyzést a következő formában: "erről az alábbi bekezdésben van szó, de ez van ebben." Mindenesetre a cikk végén található egy link a kész kódra, amelyet a cikkben leírtak figyelembevételével írnak. Csak vedd és használd. A cikk pedig elmagyarázza, miért és miért. Ha nem érdekli a "miért és miért" - görgessen le a következtetéshez és a hivatkozáshoz a példa letöltéséhez.

csak az eredményért

a határidők szigorú betartása

Átláthatóság

projekt végrehajtása

műszaki támogatás ajándékba

Programozás, 1C-vel kapcsolatos tanácsok felülvizsgálata

Hogyan dolgozunk

1. Telefonon megbeszéljük a problémát. Ha rendelkezik távoli hozzáféréssel, mutassa meg a számítógép képernyőjén.

2. Becsüljük a munkát rubelben, ha a projekt nagy, ha nem - a hozzávetőleges órák száma.

3. Elvégezzük a munkát.

4. A programjában munkát vállal, ha hiányosságok vannak, azt kijavítjuk.

5. Számlát állítunk ki, Ön fizet.

Munka költsége

1. Minden munka 3 kategóriába sorolható: konzultáció, tipikus konfiguráció frissítése, új jelentés kidolgozása vagy programozása, feldolgozás, gombok stb.

3. A 10 órát meghaladó munkavégzésre előzetesen műszaki megbízás készül a munka leírásával és költségével. A munka a megbízási feltételek Önnel való megegyezése után kezdődik.

Technikai támogatás

1. Ha a korábban elfogadott munkákban hibát talál, 3 hónapon belül ingyenesen kijavítjuk.

2. Törzsvásárlóink ​​részére a munkánk esetleges hiányosságait egész évben díjmentesen kijavítjuk.

Programok vállalkozása irányításához.

Vásároljon 1C: Enterprise

Az 1C hivatalos forgalmazója vagyunk, különféle szoftvertermékeket és licenceket vásárolhat tőlünk. A „doboz” vásárlása mellett segítünk a program beállításában, tanácsadással, alapbeállításokkal.

  • Könyvelés
  • Áruház automatizálás
  • Nagyker
  • A telepítési és kezdeti beállítási súgót a csomag tartalmazza!
  • Konfigurációk finomhangolása a megrendelő igényei szerint, új modulok fejlesztése a standard konfigurációban a szükséges funkciók hiányában.
1c számvitel 1C: Kereskedelmi menedzsment 1C: Kiskereskedelem 1C: Fizetés és személyzeti menedzsment
3300 rubeltől. 6700 rubeltől. 3300 rubeltől. 7400 rubeltől.

Szerverellátás.

Azonnali beállítási szerver + 1C.

Nincs szervered? Mindegy, felveszünk és gyorsan beállítunk egy szervert a "felhőben". Kis összegért nagyon megbízható megoldást kap.

  • Elérhetőség 24/7
  • Nincs szükség saját rendszergazdára (a megtakarítás fedezi a szerver költségeit).
  • Az 1C gyors telepítése és telepítése a szerverre, 3 nap múlva már teljesen működőképes rendszere lesz.
  • Bármikor áttérhet egy helyi szerverre, ha a megoldás nem felel meg Önnek.

SMS az 1C-től

Szeretné, ha az ügyfelek időben értesülnének az akciókról, kedvezményekről? Az ügyfelek nem térnek vissza? Állítsa be az SMS-küldést közvetlenül az 1C-ről!

Cégünk gyorsan be tudja állítani az SMS küldését ügyfeleinek közvetlenül az 1C-ből. Példák automatizálható eseményekre:

  • Köszönjük a vásárlást és a bónuszok azonnali felhalmozását a következő vásárlás után.
  • Bónuszok felhalmozása a kártyára születésnapi ajándékként \ más jelentős vagy ünnepnapra.
  • Értesítés az áruk raktárba érkezéséről.
  • Az ajándékbónuszok lejárata.
  • Értesítés az előleg beérkezéséről és árufoglalásról.
  • Cím az üzletbe/irodába való eljutás részleteivel, telefonszámokkal.
  • Stb.

A beállításokat az 1C-ben szakembereink vagy alkalmazottaink végezhetik el. A tarifákkal az SMS tarifák oldalon lehet megismerkedni.

  • SMS kézbesítési garancia, pénzfelvétel csak a kézbesített SMS után történik.
  • Minden SMS-hez külön számlázás.
  • Egyenleg-utánpótlás különböző módokon.
  • Bármikor megtekintheti az összes elküldött SMS előzményét.
  • A feladó neve az üzenet címzettjének telefonján szereplő digitális szám helyett.

Az objektum-orientált programozás (OOP) az osztály fogalma mellett az interfész alapfogalmát is tartalmazza.

Mi az az interfész, és milyen jellemzői vannak a Delphi programozási nyelven való használatának?

Az interfész egy szemantikai és szintaktikai konstrukció a programkódban, amely egy osztály vagy összetevő által nyújtott szolgáltatások meghatározására szolgál (Wikipédia).

Valójában az interfész meghatározza azon tulajdonságok és metódusok listáját, amelyeket az interfészt megvalósító osztállyal való munka során kell használni, valamint ezek aláírását (név, adattípus, elfogadott paraméterek (eljárásokhoz és függvényekhez), stb.). Így egy adott interfészt megvalósító osztálynak szükségszerűen minden összetevőjét implementálnia kell. Ráadásul szigorúan az abban leírtak szerint.

Az interfészeket gyakran hasonlítják össze absztrakt osztályokkal, de a hasonlóság ellenére ez az összehasonlítás nem teljesen helyes. Az absztrakt osztályokban legalább a tagok láthatóságának szabályozása elérhető. Ugyanakkor az interfészekhez nincs hatókör meghatározva.

Az interfészek lehetővé teszik az architektúra rugalmasabbá tételét, mivel egyesítik az egyes funkciókhoz való hozzáférést, és lehetővé teszik számos osztályörökléssel kapcsolatos probléma elkerülését (az interfészek örökölhetők egymástól).

Interfész Delphiben deklarálásához használja az interface kulcsszót. Ez ugyanaz a kulcsszó, amely meghatározza az egység azon részét, amely kívülről elérhető (a kulcsszavak felülete és az implementáció között). Egy interfész deklarálásakor azonban más szintaxist használnak, hasonlóan az osztálydeklarációkhoz.

Delphi / Pascal

IMyNewInterface = interfész eljárás InterfaceProc; vége;

IMyNewInterface = interfész

eljárás InterfaceProc;

vége;

Így maga az interfész deklaráció szintaxisa alapvetően nem különbözik a többi programozási nyelvtől (a Pascal alapú szintaxis jellemzői nem számítanak). Ugyanakkor az interfészek megvalósításának számos jellegzetessége van.

A lényeg az, hogy a Delphi interfészt eredetileg a COM technológia támogatására vezették be. Ezért az IIinterface interfész, amely a Delphiben az összes többi interfész őse (a TObject egyfajta analógja), már három alapvető módszert tartalmaz a technológiával való munkavégzéshez: QueryInterface, _AddRef, _Release. Ennek eredményeként, ha egy osztály implementál bármilyen interfészt, akkor ezeket a metódusokat hiba nélkül meg kell valósítania. Még akkor is, ha ezt az osztályt nem COM-mal való együttműködésre tervezték.

Az IInterface interfész ezen tulajdonsága miatt a Delphiben az interfészek használata a legtöbb esetben azt eredményezi, hogy szándékosan nem használt képességeket adnak az osztályhoz.

Létezik egy TInterfaceObject könyvtárosztály, amely már tartalmazza ezeknek a metódusoknak az implementációját, és ha onnan öröklődik, nincs szükség saját maga implementálni. De mivel a Delphi nem támogatja a többszörös osztályöröklést, használata gyakran csak további nehézségeket okoz a már szükséges funkcionalitás tervezésében és megvalósításában.

Mindez oda vezetett, hogy az interfészek adta lehetőségek ellenére gyakorlati felhasználásuk a Delphiben szinte nem haladta meg a COM-mal való együttműködést.

Főleg ezzel a technológiával való munkára optimalizálva az interfészek, vagy inkább az általuk felépített funkcionalitás és architektúra korlátai hiba nélkül nem indokolják magukat más problémák megoldása során.

Emiatt sok Delphi programozó még mindig nem rendelkezik hatékony és rugalmas eszközzel az alkalmazásarchitektúra fejlesztéséhez.

Ossza meg ezt