Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
1
Web programozás és haladó fejlesztési technikák
DLL Reflexió A féléves feladat struktúrája
2
Web programozás és haladó fejlesztési technikák
DLL Reflexió A féléves feladat struktúrája
3
A legegyszerűbb „Hello world”
Hello1.asm
4
Ugyanez, függvényhívással
Hello2.asm
5
Ha nincs minden függvény ugyanott
Hello3a.asm Hello3b.asm
6
Code, Compile, LINK – static linking!
7
KÜLSŐ OBJECT/LIBRARY FILE-OK
Klasszikus fordítás Object File: Egy köztes kód-reprezentáció, a fordító generálja a forráskód lefordítása után Tartalmazza: az értelmezett, fordított kódot és relokációs adatokat, utóbbit a linker használja a futtatható állomány generálásához A külső library kód static linking esetén bekerül az EXE állományba; dynamic linking esetén nem FORRÁS (.cpp, .pas, .c, .cs, .*) ELŐFELDOLGOZÁS, FORDÍTÁS KÜLSŐ OBJECT/LIBRARY FILE-OK (.o, .obj, .so, .dll) SAJÁT OBJECT FILE (.o, .obj) Relokációs adatok: az adott modulból fordított 0-s cím helye alapján a metódus entry point-ok elhelyezkedése a végső EXE file-ban LINKELÉS FUTTATHATÓ FILE (.exe)
8
Static linking Az összes használt függvény/ erőforrás a programban van
Ezek helye a fordítóprogram számára ismert Így fordításkor az ezekre történő hivatkozás előre megadható, mert az adott kód a program saját címterületén található Ugyanazt a függvényt több program is külön-külön betölti pazarlás A Klasszikus (nem overlay) DOS programok (pl: Turbo Pascal) Program SomeFunct1 SomeFunct2 SomeFunct3 Constant1 Constant2 Constant3 Main Code . @SomeFunct3 @SomeFunct1
9
Dynamic linking Egyes függvények/erőforrások a program saját címterületén kívül vannak Ezek helye a fordítóprogram számára nem ismert Így fordításkor az ezekre történő hivatkozás dinamikus, futási időben derül ki a pontos hely (a betöltést az OS végzi, Dynamically Linked) Ugyanazt a függvényt több program is együtt használja megosztott erőforrás (Shared Object) A Legtöbb modern program így működik Program 1 . @SomeFunct2 DLL SomeFunct2 SomeFunct3 Program 2 . @SomeFunct3
10
Static vs Dynamic Linking
11
Dynamic Link Library / Shared Object
A mai operációs rendszerek felhasználó számára elérhető programjai/moduljai kizárólagosan így működnek (bár több nyelvben is lehetséges statikus fordítást kérni, nem illik) Azonos feladatkör: Windowsban DLL file, Linuxban: SO file Külön fordított, a programhoz ténylegesen csak a futási időben kapcsolódik (= dynamic, mindkettőre igaz) A memóriába csak egyszer töltődik be, több program is használhatja (= shared, mindkettőre igaz, de .NET alatt csak korlátozottan (AppDomain)) Windows OS alatt meg kell különböztetni a natív és a felügyelt futtatható állományt: Natív (Native / Unmanaged): OS/CPU számára értelmezhető bytekód: procedurális kód, egyszerű típusok, közvetlen HW elérés is akár. Nyelvfüggetlen (bármi fordítható ilyen EXE/DLL kóddá), de platformfüggő Felügyelt (Managed): Egy (vagy több) osztály van benne, csak a .NET/JVM értelmező tud vele dolgozni Nyelvfüggetlen és platformfüggetlen (de a .NET/JVM értelmező kell hozzá) .NET esetén DLL/EXE file, JVM esetén CLASS/JAR file „Korlátozottan igaz” = AppDomain –enként egyszer
12
Tipikus futtatható állományok
Binary executables Ugyanazok a részek: Header, Imports, Data (RW/RO), Code Segment/.Text Container formátum: futtatható kód, és minden, a futtatáshoz szükséges adat Linux: ELF = Executable and Linkable Format Tipikusan kiterjesztés nélküli bináris futtatható állomány (nem script futtatható állomány!) vagy SO file Kiemelt extra feature: fatELF = több platformfüggő futtatható állomány egyetlen platformfüggetlen file-ban Windows: PE = Portable Executable Minden EXE/DLL file Kiemelt extra feature: ikon elhelyezése a file-ban (ELF-ben is: elfres), „egyszerűbb” (non-global) import namespaces
13
„Hello world”, Windows PE
14
RDATA
15
RDATA, DATA, CODE/TEXT
16
Natív DLL-ek Az aktuális könyvtárból vagy a %PATH%-ból töltődik be
%PATH% = a WINDOWS, SYSTEM, SYSTEM32 könyvtárak Lassú betöltődés DLL HELL Verziózás nem megoldott Ugyanazon DLL-ből különféle alkalmazások különféle verziót igényelnek A több különféle verziójú DLL együtt problémát okoz, törléskor különösen „Megoldás”: DLL stomping VAGY minden DLL az EXE mellett… Linux megoldás: file szintű csomagkezelő + verziózott symlinkek .NET megoldás: GAC = Global Assembly Cache, ld. később Windows API Unmanaged DLL-ek gyűjteménye, rendszer-hívásokkal Alacsony szintű műveletvégzés, hardver-elérés Az operációs rendszer minden publikus funkcionalitása elérhető A fontosabbakhoz létezik .NET osztály, de a legalsó szinten akkor is a WINAPI hívódik (pl. System.Diagnostics.Stopwatch = QueryPerformanceCounter)
17
Natív DLL hívása Platformfüggő natív kód Nyelvfüggetlen? Mi érhető el?
32 / 64 bites (CPU szóhossz függő) OS függő Nyelvfüggetlen? Elvileg igen, de…. Paraméterek átadása Eredmény visszaadása Ki mit szabadít fel? Lehetőségek: cdecl, stdcall, fastcall, … Mi érhető el? Saját programból nem dönthető el, fejlesztés közben ellenőrizendő dumpbin /exports A felhasznált DLL függőségei Dependency Walker
18
Natív DLL hívása C# nyelven
A programhoz szigorúan csak futási időben csatolt Tényleges ellenőrzést (létezik –e a DLL, létezik –e a benne lévő entry point) a fordító nem végez Platform Invoke (P/Invoke: natív bytekód hívása felügyelt környezetből) DllImport attribútum using System.Runtime.InteropServices; [DllImport("winmm.dll", SetLastError = true)] static extern bool PlaySound(string pszSound, UIntPtr hmod, uint fdwSound); string fname PlaySound(fname, UIntPtr.Zero, 1); WINAPI Szignatúrák, importok:
19
Managed/Unmanaged
20
Eszközök gacutil.exe NuGet Dotpeek (ILDasm, Reflector …)
DLL regisztrálása / törlése a GAC-ból, itt vannak a hivatalos .NET DLL-ek is Kezelhetőek a különféle verziók és függőségek MSDN-en megtalálható, hogy melyik osztály/névtér melyik DLL-ben található NuGet Központi .NET csomagkezelő, tipikusan felügyelt DLL állományokhoz Tools/NuGet Package Manager/Manage NuGet Packages for Solution Powershell parancssori felületből is kezelhető (Install-Package) Szinte az összes C# library/tool letölthető Függőségek/frissítések kezelése Consolidate: ellentmondó verziók kezelése Dotpeek (ILDasm, Reflector …) .NET DLL/EXE állományok kódjának tanulmányozását engedik meg Reflexió segítségével is kinyerhető információk megjelenítése (később) C# kód visszafejtése (többnyire használható formában, kivéve ha Code Obfuscator-t használunk)
21
Felügyelt DLL-ek Minden metódus egy DLL hívás volt, amit eddig használtunk Egy projekt „References” része tárolja azt, hogy mely felügyelt DLL-ek érhetőek el az adott projektből, ezt kell szerkeszteni A fordító is ellenőrzi a DLL és az osztály/metódus meglétét Gyors betöltődés, ugyanolyan sebességű, mintha a saját kód lenne Felügyelt DLL hívása Referencia hozzáadása: Project/Add reference Ezután a DLL-ben tárolt névtér és az abban tárolt osztályok/metódusok a szokványos módon elérhetőek EXE vagy DLL? .NET-en belül nincs nagy különbség, mindkettő felügyelt osztályokat tartalmaz, ugyanolyan köztes kód formában Az EXE klasszikus (PE) része csak a CLR értelmezőt tölti be Az EXE file-on belül van egyetlen static void/int Main() Projekttípus: Console App / WPF vagy Windows Forms / Class Library DLL HELL: verziózás hiánya, régi verzióval történő felülírás, nincs központi tár
22
Managed Asembly tartalma
Assembly ~ Szerelvény ~ Futtatási egység ~ managed .NET EXE/DLL állomány (Semmi köze az assembly nyelvhez!) Assembly Manifest/Metadata Név Verzió Culture/Localization információk Belső file/erőforrás lista Type metadata Referencia-lista Minden információ a típusokról Reflexióval kinyerhető (később) IL/CLR kód Erőforrások
23
Felügyelt DLL betöltése
Fusion A .NET-en belüli modul, amely a felügyelt DLL-ek betöltését végzi „Assembly binding”: felügyelt Assembly futtatásakor a references részben hivatkozott külső Assembly-k megkeresését és betöltését végző műveletsor Naplózás engedélyezése: fuslogvw.exe / Registry bejegyzések DLL HELL: verziózás hiánya, régi verzióval történő felülírás, nincs központi tár
24
Felügyelt Assembly futtatása
AppDomain A .NET assembly és az OS folyamat közötti réteg A kód végrehajtásának és az erőforrások elérésének szabályozása Pl. web esetén az azonos weboldalhoz (Virtual Directory-hoz) tartozó .NET alkalmazások azonos erőforrásokat érhetnek el, még akkor is, ha esetleg különböző .NET assembly-ről beszélünk... Különböző weboldalakhoz tartozó folyamatok különböző erőforrásokat érhetnek el, még akkor is, ha ugyanaz az EXE file fut több példányban Több AppDomain is létezhet egyetlen Win32 folyamaton belül Folyamaton belüli erőforrás-leválasztás válik lehetségessé sandboxing DLL HELL: verziózás hiánya, régi verzióval történő felülírás, nincs központi tár
25
Futtatási folyamat (.NET)
26
Web programozás és haladó fejlesztési technikák
DLL Reflexió A féléves feladat struktúrája
27
Reflexió A reflexió az a képesség, amellyel a program önmaga struktúráját és viselkedését futásidőben analizálni és alakítani tudja Magas szintű nyelv kell hozzá (Java, PHP, … C#) Különböző mértékű támogatás a nyelvekben C#-ban a leggyakoribb használati módja a futásidőben végrehajtott típusanalízis De lehetséges típusok futásidejű létrehozása is: System.Reflection.Emit Több technológia használja Intellisense, Properties és más IDE-szolgáltatások Több .NET technológia (szerializáció, .NET Remoting, WCF) Tesztek Hátránya: NAGYON LASSÚ!!!
28
Metaadat Visual Studio Command Prompt / Ildasm.exe, Ctrl+M
29
Futásidejű típusanalízis - Assembly
Assembly a = Assembly.GetExecutingAssembly(); Assembly a = Assembly.LoadFrom(„Path.To.Assembly”); Assembly a = Assembly.Load(bytes); Assembly a = type.Assembly; a.GetTypes() – típusok kinyerése eredmény: Type[] a.EntryPoint – belépési pont (metódust ad vissza, csak exe file-ok esetén)
30
Futásidejű típusanalízis - Type
Type t = assembly.GetType(„Type.Name.In.Assembly”); Type t = typeof(int); Type t = typeof(T); Type t = obj.GetType(); Type t = Type.GetType(„Type.Name.In.Any.Assembly”); Ha nem az aktuálisan végrehajtódó szerelvényben vagy az mscorlib.dll-ben van, akkor ún. „assembly-qualified name” megadása szükséges t.FullName, t.AssemblyQualifiedName – nevek különféle formában t.BaseType, t.IsSubclassOf(anotherType), t.IsAssignableFrom(anotherType) – ős, utód vizsgálat typeName can be the type name qualified by its namespace or an assembly-qualified name that includes an assembly name specification. See AssemblyQualifiedName. If typeName includes the namespace but not the assembly name, this method searches only the calling object's assembly and Mscorlib.dll, in that order. If typeName is fully qualified with the partial or complete assembly name, this method searches in the specified assembly. If the assembly has a strong name, a complete assembly name is required. TopNamespace.SubNameSpace.ContainingClass+NestedClass, MyAssembly, Version= , Culture=neutral, PublicKeyToken=b17a5c561934e089
31
Futásidejű típusanalízis – xxxInfo
PropertyInfo pi = t.GetProperty("PropName"); PropertyInfo[] pis = t.GetProperties(); FieldInfo fi = t.GetField("FieldName"); FieldInfo[] fis = t.GetFields(); MethodInfo mi = t.GetMethod("MethodName"); MethodInfo mis = t.GetMethods(); Általában átadható BindingFlags paraméter, amivel a keresés szűkíthető/konfigurálható PropertyInfo pi = t.GetProperty("PropName", BindingFlags.Static | BindingFlags.NonPublic) Nem publikus (privát) tagok is megkaphatók Ez (elsősorban) nem arra való, hogy kijátsszuk a láthatóságokat!
32
Reflektált kódelemek használata futásidőben
A reflexióval elért típusok/tagok futásidőben felhasználhatóak List<int> something = new List<int>(); something.Add(8); int cnt = something.Count; Lassabb, mint a nem reflexív kód csak akkor, ha máshogy nem megoldható (pl. egy metódus paramétere „teljesen ismeretlen”, aminek meghívjuk az Add metódusát / Count tulajdonságát) Hasonlóan flexibilis kód, sokkal gyorsabb, de compiler/intellisense segítség nélkül dynamic (DLR) Type listType = typeof(List<int>); MethodInfo addMethod = listType.GetMethod("Add"); PropertyInfo countProperty = listType.GetProperty("Count"); object listInstance = Activator.CreateInstance(listType); object methodResult = addMethod.Invoke(listInstance, new object[] { 8 }); // null object propertyResult = countProperty.GetValue(listInstance); // 1
33
Attribútumok A fordító által generált metaadat mellé saját metaadat is felvehető Szerelvény, típus vagy tagok esetében is System.Attribute osztály utódai Léteznek beépített attribútumtípusok különféle célokra, vagy saját Attribute utód is létrehozható Használata speciális formában történik Névtér, osztály, metódus, tulajdonság, mező stb. fölött – attribútumtól függően ahol engedélyezett Formátuma: [XXX], ha az Attribute utódosztály neve XXXAttribute Példa src: [Obsolete("Do not use this method, use the NewMethod() instead.")] static void OldMethod() { } static void NewMethod() { } static void Main(string[] args) { OldMethod(); //Warningot eredményez }
34
Tipikus használati esetek
Az attribútum a jelölt tag szokványos használatát nem befolyásolja Minden metódus, tulajdonság, stb. ugyanúgy meghívható/elérhető Kell egy „másik fél”, ami az attribútum meglétét majd reflexióval figyeli, és attól függően hajt végre lépéseket Tipikus felhasználása: automatizmusok/ellenőrzések Másik programozó segítése: Obsolete, DisplayName, Description Visual Studio, debugger viselkedése: DebuggerDisplay, DebuggerStepThrough Visual Studio, automata generálás: WebMethod, ServiceContract, OperationContract, FaultContract, DataContract, DataMember Kód használhatósága: Serializable, Flags, ThreadStatic, DllImport Automatizmusok támogatása: TestFixture, TestCase, TestCaseSource, Key, ForeignKey, Column Egyéb (saját) metaadatok: saját attribútumokkal Obsolete – elavult tag jelzése DisplayName – PropertyGrid vezérlőkben használt tipikusan Description – vajonmi DebuggerDisplay – ezt jeleníti meg debug közben DebuggerStepThrough – nem lehet belelépni F11 gombbal WebMethod – WCF REST kívülről hívható metódus; a többi WCF SOAP attribútum Serializable – vajonmi DllImport – DLL-ből való export használata Flags – Enumra rakható, használható a bitwise OR ThreadStatic – Szálanként statikus TestClass, TestMethod – Unit teszteknél ezekkel jelöljük h hol vannak a tesztek Key, ForeignKey, Column – EF code-first esetén ezzel jelölhetjük a későbbi táblák kulcsait, vagy esetleg az oszlop-leképezést
35
Attribútumok Példa: CallerMemberName
Ha a paraméter nem kap értéket, akkor a hívó neve kerül bele protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } class Settings { private string someSetting; public string SomeSetting get { return someSetting; } set { someSetting = value; OnPropertyChanged(); } }
36
Attribútumok Példa: Szerializáció (=adat tárolható formába alakítása, a példában bináris) [Serializable] class Settings { public string Setting1 { get; set; } public int Setting2 { get; set; } [NonSerialized] private int temp; } class Program static void Main(string[] args) Settings settings = new Settings(); //... BinaryFormatter formatter = new BinaryFormatter(); using (FileStream stream = new FileStream("settings.dat", FileMode.Create)) formatter.Serialize(stream, settings); } //mentett információ visszaolvasása: FileMode.Open, Deserialize() A példában bináris, de van még csomó más féle.
37
Saját attribútum Saját attribútum létrehozása
Attribútum elérése reflexióval Az eddig említett módszerek is ezt használják [AttributeUsage(AttributeTargets.Property)] class HelpAttribute : Attribute { public string HelpURL { get; private set; } public HelpAttribute( string helpURL) this.HelpURL = helpURL; } [Help(" public string Setting1 { get; set; } //PropertyInfo propertyInfo = typeof(Settings).GetProperty("Setting1"); HelpAttribute helpAttribute = propertyInfo.GetCustomAttribute<HelpAttribute>(); Console.WriteLine(helpAttribute.HelpURL);
38
Annotációk Más nyelvekben (Java/PHP) hasonló célú nyelvi elem PHP Java
Teljesen a kikommentezett részben van Tipikusan az IDE/külső eszköz számára értelmezhető Futás közben nem használható Java Fordító számára értelmezett A fordított osztályokban is megmarad Futás közben is kiolvasható:
39
Web programozás és haladó fejlesztési technikák
DLL Reflexió A féléves feladat struktúrája
40
Használandó eszközök és struktúra
Projektfeladat: a weboldalról letölthető roadmap követése Szabályok: a /prog3 weboldalról letölthető prog_tools és prog3_requirements dokumentumok Használandó eszközök Egy felhasználós, egy branch-et használó GIT repository A kód legyen FXCop/StyleCop-helyes, az oenik.ruleset rulesetet kell használni DoxyGen segítségével generált HTML/CHM formátumú fejlesztői dokumentáció (PDF: opcionális, LaTeX segítségével) Projekt struktúra Adatbázis használata + Entity Framework az eléréshez + LINQ lekérdezések Unit tesztekkel ellátott kód (tipikusan az üzleti logika osztályaira) Rétegezett architektúra (a konzol alkalmazástól leválasztott műveletvégző és adatbázis-kezelő DLL-ekkel) Tipikusan 1 solution, minimum 4 C# projekt: konzol alkalmazás + üzleti logika (class library) + DB (class library) + tests (class library) Külön könyvtárban NetBeans projekt
41
Git Git repository Jelenleg egy branch és egy user Git conflicts
Verziókövetés: tudjuk, hogy melyik sort ki/mikor szerkesztette Local repository, remote repository, commit, push, pull, branch, fork, merge Egy könyvtáron belül egy C# és egy Java projekt-alkönyvtárt kezelünk Nem a VS, hanem külső GIT kliens használata javasolt (parancssori / TortoiseGit / Sourcetree) Jelenleg egy branch és egy user Jelenleg egyszerű „mirror”, több branch/user a következő félévben Bitbucket.org , Private repository Kötelezően hozzáadandó admin joggal: oe_nik_prog Git conflicts Merge esetén, ha ellentmondás van a két branch között Azonos file-ban, de különböző területre vonatkozó commitok esetén sokszor automatikusan megoldódik (automatic merge) Azonos területre vonatkozó commit esetén manuális: keep A/local/ours, keep B/remote/theirs, run mergetool (kdiff3, Meld, Kompare)
42
FxCop Nem csak a kód futási eredménye/teljesítménye, hanem a kód stílusa/formázása is fontos (~ coding guidelines) Figyelni kell az alapvető kód-formázási szabályokra Tagolás, sortörések Blokk jelzése MINDIG kapcsos zárójelekkel Nevek, láthatóságok Kommentezés: minden publikus tag (osztály, metódus, tulajdonság) Metódus-definíciók esetén paraméterek magyarázata Osztályok/metódusok/sorok hossza Elvárás a „zero violations” code (Analyze / Run Code Analysis on solution) Javasolt nem utolsó pillanatra hagyni, sokkoló tud lenni a hirtelen megjelenő 8571 warning…
43
Doxygen Az FxCop miatt minden osztály/metódus/tulajdonság felett dokumentációs XML kommentek lesznek Egy elkészült metódus vagy osztály fölött „///”-t gépelve létrejön A kitöltött XML dokumentáció az Intellisense-ben is megjelenik A kommentek nyelve: ANGOL A Doxygen ebből generál „fogyasztható” dokumentumot Alapértelmezetten HTML formátum (csak ez az elvárt) HTML Help builder használatával könnyedén generálható CHM dokumentáció LaTeX használatával könnyedén generálható PDF dokumentáció Parancssori változattal vagy a Doxywizard GUI segítségével A meglévő C# és Java forrás publikus tagjait dolgozza fel A public láthatóságú tagok mellett javasolt az internal láthatóságú tagok feldolgozásának bekapcsolása is (EXTRACT_PACKAGE - ha sok Internal/Package-only osztályunk van: kötelező) A HTML kimenetet a GIT repository-ba rakjuk bele, egy commitban menjen fel az egész a leadás előtt néhány órával/nappal
44
Források Miklós Árpád prezentációja
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.