Dostęp do funkcji niskopoziomowych w.net Compact Framework



Podobne dokumenty
Języki i metodyka programowania. Język C# pętle, sterowanie, wyjątki

Programowanie Komputerów

Microsoft IT Academy kurs programowania

Programowanie C# mgr in. Dariusz Ku. p. 119A

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Wyjątki (exceptions)

Programowanie obiektowe

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Wykład 12. Programowanie serwera MS SQL 2005 w C#

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Język ludzki kod maszynowy

Programowanie w środowiskach graficznych. Wykład 3 Język C#

Metodyka programowania. Podstawy C#

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

Programowanie współbieżne i rozproszone

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Wykład 8: klasy cz. 4

Programowanie Obiektowe Ćwiczenie 4

Ada-95. Dariusz Wawrzyniak

Zaawansowane aplikacje WWW - laboratorium

MATERIAŁY DO ZAJĘĆ II

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Wykład 5: Klasy cz. 3

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Klasy Obiekty Dziedziczenie i zaawansowane cechy Objective-C

Wykład 3 Składnia języka C# (cz. 2)

Ćwiczenia laboratoryjne. Oprogramowanie i badanie prostych metod sortowania w tablicach

Klasy cd. Struktury Interfejsy Wyjątki

2 Przygotował: mgr inż. Maciej Lasota

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Dokumentacja techniczna API systemu SimPay.pl

Programowanie obiektowe

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

Wykład 1

Kiedy potrzebne. Struktura (rekord) Struktura w języku C# Tablice struktur. struktura, kolekcja

Wykład 4 Delegat (delegate), właściwości indeksowane, zdarzenie (event) Zofia Kruczkiewicz

Ekspert radzi. mechanizm w enova, umożliwiający wskazanie domyślnej drukarki dla danego stanowiska i wydruku. Strona 1 z 8. Ekspert radzi.

Obsługa wyjątków. Język C++ WW12

EGZAMIN PROGRAMOWANIE II (10 czerwca 2010) pytania i odpowiedzi

Programowanie obiektowe

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Podstawy i języki programowania

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Programowanie obiektowe

Multimedia JAVA. Historia

Programowanie obiektowe

Grzegorz Cygan. Wstęp do programowania mikrosterowników w języku C

Wprowadzenie do programowania

Laboratorium nr 12. Temat: Struktury, klasy. Zakres laboratorium:

Wiadomości wstępne Środowisko programistyczne Najważniejsze różnice C/C++ vs Java

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Aplikacje w środowisku Java

Zdalne wywołania procedur. Jarosław Kuchta Programowanie Współbieżne

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

- Narzędzie Windows Forms. - Przykładowe aplikacje. Wyższa Metody Szkoła programowania Techniczno Ekonomiczna 1 w Świdnicy

Wstęp do wiadomości teoretycznych (nie, nie jest to masło maślane ani wstęp, wstępów proszę cierpliwie czytać)

DYNAMICZNE PRZYDZIELANIE PAMIECI

Podstawy i języki programowania

Klasy i obiekty cz II

Rodzina protokołów TCP/IP. Aplikacja: ipconfig.

Struktury, unie, formatowanie, wskaźniki

Wykład 2: Podstawy Języka

Tworzenie aplikacji w języku Java

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Programowanie strukturalne język C - wprowadzenie

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Wykład 2 Składnia języka C# (cz. 1)

Szablony funkcji i szablony klas

Języki i metodyka programowania. Wprowadzenie do języka C

external Data Representation

Wykład 5 Okna MDI i SDI, dziedziczenie

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Wykład 3 Typy danych w C++/CLI, typy fundamentalne, operacje wejścia/wyjścia, właściwości klasy (property) Zofia Kruczkiewicz

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Podstawy Programowania Obiektowego

Programowanie obiektowe

Programowanie obiektowe

Metody Metody, parametry, zwracanie wartości

Programowanie 2. Język C++. Wykład 3.

Kompilator języka C na procesor 8051 RC51 implementacja

Programowanie obiektowe

Funkcje w PL/SQL Funkcja to nazwany blok języka PL/SQL. Jest przechowywana w bazie i musi zwracać wynik. Z reguły, funkcji utworzonych w PL/SQL-u

Programowanie w Javie

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak

Podejście obiektowe. Tablice obiektów Przykład 1 metody i atrybuty statyczne oraz niestatyczne

Praca w środowisku Visual Studio 2008, Visual C

Wywoływanie metod zdalnych

Typ użyty w deklaracji zmiennej decyduje o rodzaju informacji, a nazwa zmiennej symbolicznie opisuje wartość.

W powyższym kodzie utworzono wyliczenie dni tygodnia.

Transkrypt:

Programowanie urządzeń mobilnych Laboratorium Dostęp do funkcji niskopoziomowych w.net Compact Framework

Wstęp Technologia.NET Compact Framework dostarcza deweloperom oprogramowania bardzo wiele możliwości w rozwijaniu aplikacji przeznaczonych na urządzenia mobilne. Firma Microsoft, oprócz środowiska programistycznego i licznych narzędzi wspomagających tworzenie kodu, daje także dostęp do wielu bibliotek i gotowych obiektów ułatwiających wykorzystywanie możliwości, jakie dają urządzenia przenośne. Z uwagi na łatwość wykorzystywania i dobrą dokumentację najpopularniejszym językiem tworzenia kodu jest C#, a samo tworzenie aplikacji opiera się na wytwarzaniu tzw. kodu zarządzalnego (ang. managed code), czyli obsługiwanego przez.net Compact Framework CLR (ang. Common Language Runtime), tak jak to zostało przedstawione na Rys. 1. Rozwiązanie to przyśpiesza proces tworzenia samego kodu aplikacji, czyni go bardziej czytelnym, tym samym obniżając koszty całego procesu tworzenia oprogramowania. Rys. 1. Kodowanie natywne a kodowanie a tworzenie kodu zarządzalnego. Czasami jednak zachodzi potrzeba tworzenia bardziej zaawansowanych funkcji dla wymagających użytkowników telefonów komórkowych, w tym przypadku dostęp do niskopoziomowych funkcji Windows Mobile jest bardzo przydatny.

W niniejszym ćwiczeniu pokazany zostanie mechanizm Platform Invocation Service, zwany także P/Invoke lub Pinvoke, który umożliwia wywoływanie z poziomu kodu zarządzalnego funkcji systemowych zawartych w natywnych bibliotekach DLL. Mechanizm P/Invoke Zastosowanie mechanizmu P/Invoke składa się z trzech podstawowych etapów: deklaracji, wywołania, obsługi błędów. DEKLARACJA Na samym początku realizacji mechanizmu wywołania funkcji Win API musimy wiedzieć jaką dokładnie funkcje chcemy wywołać, czyli musimy znać: nazwę biblioteki DLL w której funkcja się znajduje, nazwę samej funkcji (w literaturze anglojęzycznej i dokumentacji możemy napotkać na nazwę entry point ), sposób wywołania (ang. calling convention), zależny głównie od platformy językowej w której piszemy aplikacji (C++, C#, VB). W laboratorium ograniczymy się do wywoływania funkcji systemowych z języka C# za pomocą atrybutu DllImport jak pokazuje fragment kodu poniżej: //using System.Runtime.InteropServices;!! [DllImport("coredll.dll", SetLastError = true)] private static extern bool SHGetSpecialFolderPath( IntPtr hwndowner, StringBuilder lpszpath, int nfolder, int fcreate); W tym przypadku zamieściliśmy deklarację funkcji umożliwiającej pobranie domyślnych ścieżek folderów systemowych w systemie WindowsCE. Oprócz nazwy funkcji

SHGetSpecialFolderPath zamieszczona została także nazwa biblioteki dll, do której się będziemy odwoływać, oraz liczba i typ parametórw wejściowych. Należy także zwrócić uwagę na fakt, iż funkcja została zadeklarowana jako zewnętrzna (extern) i statyczna. Modyfikatory te oznaczają że ciało funkcji jest zaimplementowane poza obrębem deklaracji (extern), a co za tym następuje, funkcja jest dostępna niezależnie od instancji klasy (static). Omawiana funkcja pobiera argument typu cefolders. W praktyce oznacza to, że funkcja wymaga wartości CSIDL (ang. constant special item ID list) wskazującą na jedną że stałych w Windows CE API. Dokładne informację na temat stałych w Windows CE można znaleźć w dokumentacji albo na stronie MSDN (www.msdn.com). Pomocne zatem, może być stworzenie zbioru stałych a podstawie listy CSIDL, która będzie nam definiowała najważniejsze foldery: const int CSIDL_FAVORITES = 0x0006; const int CSIDL_FONTS = 0x0014; const int CSIDL_PERSONAL = 0x0005; const int CSIDL_PROGRAM_FILES = 0x0026; const int CSIDL_PROGRAMS = 0x0002; const int CSIDL_STARTUP = 0x0007; const int CSIDL_WINDOWS = 0x0024; UWAGA!! W niektórych przypadkach może zdarzyć się tak, iż nazwa funkcji w bibliotece DLL będzie kolidowała nam z jednym słów kluczowych C# albo z nazwą innej funkcji. Projektanci platformy.net Compact Framework przewidzieli taką sytuację i stworzyli system nadawaniu aliasów dla deklaracji funkcji natywnych: [DllImport("coredll.dll", EntryPoint="SHGetSpecialFolderPath")] static extern bool GetFolderPath( //reszta deklaracji funkcji WYWOŁANIE Mając prawidłową deklarację funkcji natywnej możemy zaimplementować jej wywołanie. Wywołanie samej funkcji najczęściej implementuje się w ciele specjalnie

przeznaczonej do tego metody typu static tak, aby funkcja natywna mogła być wywołana bez konieczności tworzenia obiektu klasy, w której jej deklaracja została zaimplementowana. Przykładowe wywołanie pokazuje kod poniżej: bool ret = false; StringBuilder resultpath = new StringBuilder(255); try ret = SHGetSpecialFolderPath((IntPtr)0,resultPath,CSIDL_STARTUP,0); catch(exception ex) //HandleCeError(ex, "GetSpecialFolderPath"); return "blad"; if (!ret) Console.Error.WriteLine("API Error"); int errornum = Marshal.GetLastWin32Error(); return resultpath.tostring(); OBSŁUGA BŁĘDÓW W kodzie powyżej pokazano jedynie przykład tego jak można wywołać funkcje natwyną z kodu zarządzalnego oraz przedstawiono prosty przykład obsługi błedów za pomocą wyjątków. W celu dokładniejszego stwierdzenia przyczyny ewentualnie powstałych wyjątków dobrze jest dodatkowo zaimplementować funkcję obsługującą powstałe wyjątki (np. HandleCeError(...)), w której można dokładnie przeanalizować przyczynę nieprawidłowości. Przykładowy kod metody HandleCeError został pokazany poniżej: private static void HandleCeError(Exception ex, string method) if (ex.gettype() == (typeof(notsupportedexception))) throw new WinCeException("Bad arguments or incorrect declaration in " + method, 0, ex); //entry not found if (ex.gettype() == typeof(missingmethodexception)) throw new WinCeException("Entry point not found in " + method, 0, ex); if (ex.gettype() == typeof(winceexception)) throw ex;

//All other exceptions throw new WinCeException("Miscellaneous exception in " + method, 0, ex); PRZEKAZYWANIE DANYCH (ang. MARSHALLING DATA) Istotnym elementem w programowaniu z użyciem kodu zarzadzalnego i natywnego jest przekazywanie danych z i do funkcji natywnych. W przypadku CLR (ang. Common Language Runtime) istnieje szereg reguł i metod definiujących sposób przekształacania i interpretacji danych pomiędzy CLR a Win API. W naszym przypadku ograniczymy się jedynie do najważniejszych postulatów, które powinny wystarczyć aby prawidłowo korzystać z najwązniejszych funkcji Win API. Typy nymeryczne Większość bilbiotek systemu Windows jest napisana z użyciem języka C, a co za tym idzie, większość stałych i zmiennych wykorzystywanaych w funkcjach Win API pochodzi od podstawowych typów języku C bądź ich modyfikacji wynikających ze stosowania definicji typów bądź MACRO. Zatem, w przypadku typów numerczyncych próbójąc przekazać bądź odebrać zmienną z lub do Win API musimu znać odpowiedzi na następujące pytania: czy zmienna jest stało- czy zmienno-przecinkowa? Jeśli zmienna jest stało przecinkowa, czy jest ze znakiem (signed) czy bez znaku (unsigned)? Jeśli zmienna jest stało przecinkowa to na ilu bitach jest zapisywana? Jeśli zmienna jest zmienno-przecinkowa to czy jest typu single- czy doubleprecision? Czasami odpowiedź na poniższe pytania jest oczywista czasami wyamaga zastanowienia. Poniższa tabelka może być pomocna w programowaniu na Win API:

Typy Win API Specyfikacja Typy.NET (CLR) char, INT8, SBYTE, CHAR 8-bit signed integer System.SByte short, short int, INT16, 16-bit signed integer System.Int16 SHORT int, long, long int, INT32, 32-bit signed integer System.Int32 LONG32, BOOLâ, INT int64, INT64, 64-bit signed integer System.Int64 LONGLONG unsigned char, UINT8, 8-bit unsigned integer System.Byte UCHARâ, BYTE unsigned short, UINT16, 16-bit unsigned integer System.UInt16 USHORT, WORD, ATOM, WCHARâ, wchar_t unsigned, unsigned int, 32-bit unsigned integer System.UInt32 UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT unsigned int64, UINT64, 64-bit unsigned integer System.UInt64 DWORDLONG, ULONGLONG float, FLOAT Single-precision floating System.Single point double, long double, DOUBLE Double-precision floating point System.Double Tabela 1. Typu Win API a typy CLR. Więcej informacji odnośnie przekazywania zmiennych pomiędzy CLR a kodem natywnym można znaleźć na stronie MSDN np.: http://msdn.microsoft.com/en-us/magazine/cc164123.aspx#s1 lub http://msdn.microsoft.com/en-us/library/aa446529.aspx ZADANIE 1 Należy zrealizować funkcję odczytu katalogu startowego (CSIDL_WINDOWS_STARTUP) na urządzeniu Windows Mobile ZADANIE 2

Zadanie 2 polega na odczycie pełnej listy kontaktów zapisanej na karcie SIM z użyciem funkcji natywnych i wyświetleniu ich w prostym menu użytkownika. UWAGA!! Istnieją dodatkowe bilbioteki (np. Smart Device Framework) umożliwiające realizację tego zadania, których na tym ćwiczeniu nie należy używać!! Zadanie ma być wykonane z użyciem kodu natywnego tak jak pokazano w opisowej części instrukcji dotyczy to wszystkich zadań na tym ćwiczeniu laboratoryjnym. WSKAZÓWKI Funkcja do odczytu kontaktu z karty SIM (PHONEBOOKENTRY) [DllImport("cellcore.dll")] private static extern IntPtr SimReadPhonebookEntry(IntPtr hsim, uint dwlocation, uint dwindex, ref SIMPHONEBOOKENTRY lpphonebookentry); Struktura simphonebookentry: internal struct SIMPHONEBOOKENTRY public uint cbsize; // @field Size of the structure in bytes public uint dwparams; // @field Indicates valid parameter values [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string lpszaddress; // @field The actual phone number public uint dwaddresstype; // @field A SIM_ADDRTYPE_*constant public uint dwnumplan; // @field A SIM_NUMPLAN_*constant [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] string lpsztext; // @field Text assocaited with the entry Niezbędne stałe: private static long SIM_PBSTORAGE_EMERGENCY = (0x00000001) ; // @constdefine Emergency dial list private static long SIM_PBSTORAGE_FIXEDDIALING = (0x00000002) ; // @constdefine SIM fixed dialing list private static long SIM_PBSTORAGE_LASTDIALING = (0x00000004) ; // @constdefine SIM last dialing list private static long SIM_PBSTORAGE_OWNNUMBERS = (0x00000008) ; // @constdefine SIM ownnumbers lists private static long SIM_PBSTORAGE_SIM = (0x00000010); // @constdefine General SIM Storage

private static long SIM_NUMPBSTORAGES = 5; Number of phonebook storages // @constdefine Proponowane wywołanie: res = SimReadPhonebookEntry((IntPtr)hSim, (uint)sim_pbstorage_sim, (uint)1, ref simentry); gdzie 1 oznacza numer kontaktu. Wynik będzie przechowywany w strukturze simentry. Kontakty numeroweane są od 1!!. Funkcja SimReadPhonebookEntry( ) zwraca wartość 0 w przypadku prawidłowego odczytu danych. W zmiennej hsim przechowywany jest adres pamięci umożliwiający zapis i odczyt danych z karty z SIM. Można go uzyskać za pomocą funkcji: [DllImport("cellcore.dll")] private static extern IntPtr SimInitialize(IntPtr dwflags, IntPtr lpfncallback, IntPtr dwparam, out IntPtr lphsim); Należy także pamiętać o zwolnieniu pamięci po wykonaniu operacji na danych SIM za pomocą funkcji: [DllImport("cellcore.dll")] private static extern IntPtr SimDeinitialize(IntPtr hsim); Więcej informacji na temat można znaleźć na stronie MSDN: http://msdn.microsoft.com/en-us/library/aa921503.aspx Uwaga!! Funckje związane z odczytem zawartości danych z karty SIM nie będą działać na emulatorze!! Zadanie 2 i 3 wykonujemy więc na telefonie komórkowym w grupach 2 osobowych (2 osoby na jeden telefon). ZADANIE 3 W zadaniu 3 należy dać użytkownikowi mozliwość wykonania połączenia na wybrany z listy wygenerowanej z zadaniu numer. Realizację wywołania połączenia telefonicznego należy zrealizować także za pomocą funkcji P/Invoke. Wskazówki

Funkcja wywołania połączenia: [DllImport("phone.dll")] private static extern IntPtr PhoneMakeCall(ref PhoneMakeCallInfo ppmci); Struktura przekazywana w argumencie: private struct PhoneMakeCallInfo public IntPtr cbsize; public IntPtr dwflags; public IntPtr pszdestaddress; public IntPtr pszappname; public IntPtr pszcalledparty; public IntPtr pszcomment;