380 likes | 523 Views
Java2C#. Antonio Cisternino Part IV. Outline. Exception handling (no throws clause) Advanced features: "preprocessor“ unsafe code interoperability: using C++ using COM Interop tlbimp/tlbexp using PInvoke Introduction to BCL. Outline. Exception handling (no throws clause)
E N D
Java2C# Antonio Cisternino Part IV
Outline • Exception handling (no throws clause) • Advanced features: • "preprocessor“ • unsafe code • interoperability: • using C++ • using COM Interop tlbimp/tlbexp • using PInvoke • Introduction to BCL
Outline • Exception handling (no throws clause) • Advanced features: • "preprocessor“ • unsafe code • interoperability: • using C++ • using COM Interop tlbimp/tlbexp • using PInvoke • Introduction to BCL
Exception handling • CLR and C# support exception handling • Structure of exceptions is similar to Java • There is no throws clause in C# • Example of Exception Handling: try { … } catch(XXXException) { … } finally { … } • Multiple catch clauses are allowed • Finally block is executed either the try block raises or not an exception
Common C# Exceptions • System.ArithmeticException • System.ArrayTypeMismatchException • System.IndexOutOfRangeException • System.InvalidCastException • System.MulticastNotSupportedException • System.NullReferenceException • System.OutOfMemoryException • System.OverflowException • System.StackOverflowException • System.TypeInitializationException
Outline • Exception handling (no throws clause) • Advanced features: • "preprocessor“ • unsafe code • interoperability: • using C++ • using COM Interop tlbimp/tlbexp • using PInvoke • Introduction to BCL
C# “preprocessor” • C# borrows from C++ the preprocessor syntax • There isn’t a separate “preprocessor”: the tokenizer implements it • Preprocessor directives are less expressive than C++: there are no macros! • Supported directives are: • #define, #undef • #if, #elif, #else, #endif • #error, #warning • #region, #endregion • #line
Conditional compilation #define DEBUG public class Stream { public void Write(string s) { #if DEBUG Console.WriteLine("Debug: " + s); #elif CONSOLE Console.WriteLine(s); #else label.Text = s; #endif } } #undef DEBUG
Warning: not pre! class Hello { static void Main() { System.Console.WriteLine(@"Hello, #if Debug world #else Pisa #endif "); } } • Output is the whole string with directives!
Other directives • Error and warning allow to detect inconsistencies in configuration at compile time • Region/endregion are directives that allow mark region of code with a label (after the region directive). Other programs will be responsible of their processing • Line directive helps code generators to associate C# code to source file (i.e. Yacc)
Conditional attribute • An important attribute is the Conditional attribute • It can be specified only for methods • If a method has such attribute its calls are included or not depending if a symbol is defined where the call is made • Example: class Foo { [Conditional("Debug")] void Baz(); } … Foo f; f.Baz(); // Not included! #define Debug f.Baz(); // Included!
Unsafe code • The base model of C# is similar to Java: no MEMORY is present • BUT C# provides a special mode called unsafe that allow using pointers! • Unsafe code is not verifiable thus high privileges are required to run it • The pointer data type is very like C pointers and introduces memory in the model • Unsafe code is needed to support PInvoke mechanism • Support from GC allows programs pinning of objects
Example class Test { unsafe static void Main() { char* p = stackalloc char[256]; for (int i = 0; i < 256; i++) { p[i] = (char)i; } *p = 64; } }
Pinning objects! unsafe class Test { static int x; int y; static void F(int* p) { *p = 1; } static void Main() { Test t = new Test(); int[] a = new int[10]; fixed (int* p = &x) F(p); fixed (int* p = &t.y) F(p); fixed (int* p = &a[0]) F(p); fixed (int* p = a) F(p); } }
Interoperability using VC++ • Visual C++ compiler is able to generate code managed and unmanged that interacts at source level! • Crossing the barrier managed/unmanaged is simplified: write standard C++ classes that uses .lib and DLLs and little managed classes that act as wrappers • The compilers is in charge of separating the two environment and output the appropriate code • In order to support managed code C++ language has been extended syntactically
Example #include <mscorlib.dll> using namespace System; class CppClass { public: CppClass() {} ~CppClass() {} void native_f() {} }; __gc class MClass { public: MClass() { m_pC = new CppClass(); } ~MClass() { delete m_pC; } void managed_f() { m_pC->native_f(); } private: CppClass * m_pC; };
Managed C++ • To indicate which elements should be managed the keyword __gc is extensively used • Managed objects are pointer to managed classes labeled with __gc • Managed classes are annotated with __gc • Other extensions are required to handle with other features such as attributes • Although it is great the ability of mixing unmanagd and managed code the program becomes more difficult to read: managed objects aren’t equivalent to C++ ones!
COM Interop • COM is the component technology used in Windows • COM allows any program sharing data and interacting with other unknown programs • The CLR itself is a COM component (and can be embedded in other applications!) • CLR supports COM interoperability in both directions: COM components can be seen as .NET objects and vice-versa
COM in one slide! • COM components are set of interfaces that inherits from IUnknown • A set of rules guarantees a notion of identity of the component instance • An interface is just a table of pointers to methods • Information about types and interfaces are defined using IDL and stored in type libraries • Components are packaged in DLLs and registered into registry • Interpreters may use IDispatch or typelibs to use COM components • It is efficient but difficult to use from languages and prone to errors • Common issues: DLLs, Registry, typelibs, and so on
Tlbimp and tlbexp • The runtime handle with most of the complexity of COM and in general is able to expose COM components into the runtime automagically • Marshalling and unmarshalling of standard types is handled by the runtime • Two utilities are available to cope with COM: tlbimp/tlbexp • Tlbimp builds an assembly that wraps a COM component • Tlbexp generates COM interfaces to CLR types
PInvoke • C# provides a mechanism called PInvoke to simplify interaction with native code • Using attributes and the extern keyword to expose as a method the function of a DLL • Example: [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)] public static unsafe extern IntPtr CreateFileMapping( IntPtr hFile, void* lpAttributes, FileProtection flProtect, int dwMaximumSizeHigh, int dwMaximumSizeLow, string lpName); • The program could use its own data types to interact with the function and specific attributes help controlling the memory layout of types
Example: pointer wrapper • Goal: expose a file mapped in memory • Steps: • Expose memory mapping functions into CLR • Write a type that represents a MM file • Write a “pointer” type that exposes the memory as an array of bytes • Cast operations help reading memory depending on data types.
public struct MapPtr { private unsafe byte* p; private unsafe byte* b; private unsafe byte* e; public MapPtr(MapPtr p, int sz) { unsafe { Debug.Assert(p.e - p.p >= sz, "Wrong window size!"); this.b = p.p; this.p = p.p; this.e = p.p + sz; }} internal unsafe MapPtr(byte* p, byte* b, byte* e) { this.p = p; this.b = b; this.e = e; } public byte this[int pos] { get { unsafe { byte* np = p + pos; Debug.Assert(np >= b && np < e, "Illegal access"); return *np; }}} public static MapPtr operator+(MapPtr p, int i) { unsafe { Debug.Assert(p.p + i <= p.e, "Illegal access"); return new MapPtr(p.p + i, p.b, p.e); }} public static long operator-(MapPtr p, MapPtr q) { unsafe { return p.p - q.p; }} public static explicit operator int(MapPtr p) { unsafe { return *((int*)p.p); }} public static explicit operator long(MapPtr p) { unsafe { return *((long*)p.p); }} public static bool operator==(MapPtr p, MapPtr q) { unsafe { return p.p == q.p; }} public static bool operator!=(MapPtr p, MapPtr q) { unsafe { return p.p != q.p; }}} Example
Outline • Exception handling (no throws clause) • Advanced features: • "preprocessor“ • unsafe code • interoperability: • using C++ • using COM Interop tlbimp/tlbexp • using PInvoke • Introduction to BCL
Introduction to BCL • BCL is organized in hierarchical namespaces • System.* namespaces and classes are considered part of the framework • Only a subset of System has been standardized within ECMA standards • A reasonable implementation of .NET should implement more than the standard subset of BCL • Additional libraries are exposed through the namespace Microsoft.* • In the following slides a brief introduction to BCL namespaces is provided: in most cases a separate course will be needed to explain the details!
Namespace System • Is the core namespace • Many types are just exposed by EE • It is like java.lang.* but more richer • Relevant classes are • System.Activator • System.Type • System.AppDomain • System.Attribute • System.Environment (Cmd line args, variables and other info) • System.GC • System.Math • System.Object • System.Random • Base value types (System.{ Byte, Int16, Int32, … })
Namespace System • Note that threads are not included in System namespace • Threading is subject of System.Threading namespace • Loading mechanism is exposed through System.Activator class • The class is sealed and classes cannot be derived from it • AppDomain exposes the bound of the managed code: many AppDomains may share the same process (and EE) but are separated • In particular types are loaded per-AppDomain • Activator + AppDomain + Assembly.LoadFrom ~= Java class loader
Namespaces • System.CodeDom: an abstraction to support DOM representing code and compiler writing • System.Collections: container classes to manipulate collection of objects (Hashtable, SortedList, …) • System.ComponentModel: base abstraction for a component model • System.Configuration: classes to support reading of XML configuration files
System.Data namespace • System.Data: under this namespace are implemented the classes of ADO.NET architecture • ADO.NET reflects the experience of Microsoft with DB interfaces: it is a flexible framework that really improves ADODB and ODBC • The architecture consists in having a set of provider (.NET assemblies) • The interface is far better than JDBC provided with Java: relation among tables and other constraints are exposed as objects • A set of interfaces allows providers to extend the architecture
Namespaces • System.Diagnostics: contains classes to support interaction with OS logging system: event logs, process management, counter handling • Debug class supports assertions and debug output! • System.Drawing: this namespace exposes classes for 2D graphics. • The Graphics class contains base primitives (also sophisticated ones such as Bezier curves) • other classes support managing of images and other drawing elements • Text and Printing namespaces take care of corresponding drawing support
Namespaces • System.Globalization: contains classes to support localization of software. MS has great experience in supporting different locales and the namespace reflects such experience. • System.IO: this namespace exposes IO management. The namespace is less stream oriented than Java although there are binary and character streams • System.IO.IsolatedStorage: support reading and writing in stores with code less trusted • System.Management: exposes WMI interface
Namespaces • System.Messaging: exposes messaging abstraction over the net • System.Net: contains high level classes to interact with TCP/IP. Sockets are exposed in System.Net.Sockets • System.Reflection: contains reflection classes. Emit namespace contains classes to generate managed programs • System.Resources: supports access to locale dependent resources
System.Runtime • Namespaces under System.Runtime exposes features of the runtime: • CompilerServices: support for compiler writers • InteropServices: important namespace that supports interoperability services (i.e. COM) • Remoting: architecture to support distributed objects. Note that remoting is supported by CLR and not implemented on top of it! • Serialization: complex architecture to support serialization of objects allowing programs to customize serialization format
Namespaces • System.Security: contains classes to manage security • System.ServiceProcess: contains support for implementing easily Windows services!!! • System.Text: supports encodings and the StringBuilder to manipulate efficiently strings • System.Text.RegularExpressions: support for perl-like regular expressions. There is a compiler to generate IL for specialized expressions written using System.Reflection.Emit.
Namespaces • System.Threading: • exposes Thread related types • Synchronization is more rich than Java • Multiple synchronization objects are provided: event, mutex, monitor, interlock • System.Timers: support for timers • System.Web: huge amount of classes to support Web applications
System.Web • Two are the main technologies behind Web namespace: • Web services • ASP.NET • Web services are simply method exposed through an XML-based protocol called SOAP (W3C). The runtime together with IIS is able to expose type’s methods labeled with appropriate attributes as Web services • ASP.NET is an attempt to support Web application development offering to the programmer an abstraction that makes a Web application similar to a Windows application. • WebForms are a set of “Web controls” that represents remote graphic elements • Events are dispatched through HTTP and the programming style may lead very inefficient programs due to event handling!
Windows Forms and XML • System.Windows.Forms: • this namespace contains support for building GUI applications. • Its structure recalls java.awt although there are significant differences. • Example: a different layout mechanism is used • System.XML is the namespace devoted to XML standards. The following standards are supported: • XML Dom • XML reader (Sax-like approach) • XML Schema • XPath • XSL and XSLT
Next lecture • Visual Studio environment • example: using DirectX from C#. • example: Web services • Framework SDK tools: gac, csc, ildasm • Assembly & co.