Presentation is loading. Please wait.

Presentation is loading. Please wait.

COM Interop & P/Invoke.NET and the Old World. Objectives Introduction to interoperation between.NET and COM COM and.NET.NET and platform services.

Similar presentations


Presentation on theme: "COM Interop & P/Invoke.NET and the Old World. Objectives Introduction to interoperation between.NET and COM COM and.NET.NET and platform services."— Presentation transcript:

1 COM Interop & P/Invoke.NET and the Old World

2 Objectives Introduction to interoperation between.NET and COM COM and.NET.NET and platform services

3 Contents Section 1: Overview Section 2: Calling COM Services from.NET Section 3: Calling.NET Services from COM Section 4: Calling Platform Services from.NET

4 Existing Stuff Must Coexist Transition to.NET will be a lasting process Portions of systems will remain as they are now...and even maintained in their current form Interoperability increases the momentum of.NET Goal is to achieve total transparency Mere presence of.NET must not interfere with COM Performance should not be hit

5 What is different in the two Worlds? Managed Code vs. Unmanaged Code Lifetime management Metadata Common Type System Inheritance concept Threading model Error handling mechanisms Registration

6 Calling COM Services from.NET Metadata for COM class must be available Can be generated from Type Library Can declare Custom Wrapper Use COM class like.NET class Early and late bound activation COM component must be registered locally

7 Early Bound Activation Instantiate like creating a.NET object Metadata must be available at compile time Must be referenced in development environment At runtime, Metadata and COM library must be available COMLib.COMClass aCOMObject; aCOMObject = new COMLib.COMClass;

8 Runtime Callable Wrappers Preserving object identity Maintaining object lifetime Proxying interfaces Marshalling method calls Consuming selected interfaces.NET Object COM Object RCW IUnknown IDispatch IIfc

9 Consuming Selected Interfaces ISupportErrorInfo Additional information with exceptions IProvideClassInfo Typed wrapper ITypeInfo TlbImp converts references to System.Type

10 Identity and Lifetime Control COM lifetime control is wrapped by RCW COM object released when RCW garbage collected Non-deterministic finalization issue COMLib.COMClass aCOMObject; aCOMObject = new COMLib.COMClass(); aCOMObject.SomeFunc(); Marshal.ReleaseComObject(aCOMObject);

11 Converting Type Library to Metadata Use SDK tool TlbImp Or just add reference to server in Visual Studio Type library can be imported from executable Reference resulting metadata file in project Custom IDL attributes are preserved IDL: [custom(„FE42746F-...-AC...84178”, “Value”)].NET: [IdlAttribute(„FE42746F-...-AC...84178”, “Value”)]

12 Conversions by TlbImp 1/2 Library level Library to namespace Module is converted to class Constants within module to constants within that class Module functions to static members of the class library COMLib { interface Widget {}; coclass Slingshot {}; } namespace COMLib { interface Widget {}; class Slingshot {}; } custom(0F21F359-AB84-41e8-9A78-36D110E6D2F9, „MyNamespace.Class")

13 Conversions by TlbImp 2/2 Interfaces Base interfaces IUnknown and IDispatch are stripped Type definitions are not imported Imported as the underlying types Properties Generates corresponding get and set Events namespace COMLib { interface Widget {}; class Slingshot {}; }

14 Marshalling Isomorphic Types Integer, Float Values Non-isomorphic Types Booleans, Chars, Strings, Arrays, Objects Copying vs. Pinning Isomorphic Types are pinned Non-Isomorphic Types are copied Watch out with Unicode Strings! Passing by value actually passes a reference! Passing by reference creates new String

15 Marshalling a Union Use attributed struct in.NET StructLayout attribute for Sequential layout – is a regular structure Default Union layout Explicit layout [StructLayout(Layout.Explicit)] public class SYSTEM_INFO { [FieldOffset(0)] ulong OemId; [FieldOffset(4)] ulong PageSize; [FieldOffset(16)] ulong ActiveProcessorMask; [FieldOffset(20)] ulong NumberOfProcessors; [FieldOffset(24)] ulong ProcessorType; }

16 Inheritance COM uses containment/aggregation.NET adds implementation inheritance Mixed-mode objects Managed objects can derive from COM objects Must have metadata available Must be instantiatable Must be aggregatable Interfaces can be inherited IUnknown, IDispatch derivation is removed

17 Calling an COM Server namespace CallingCOMServer { using System; using COMServerLib; public class DotNET_COMClient {... public static int Main(string[] args) { MyCOMServer myS = new MyCOMServer(); return (myS.Add (17,4)); } };

18 Late Bound Activation Accomplished by Reflection API No difference whether COM or.NET object Type can be obtained from ProgID or ClsID InvokeMember to access methods and properties Metadata is not needed, but useful COM object is wrapped by __ComObject

19 Late Bound Call to COM Server namespace LateBoundClient { using System.Reflection;... Type typ; Object obj; Object[] prms = new Object[2]; int r; typ = Type.GetTypeFromProgID(„MyLib.MyServer"); obj = Activator.CreateInstance(typ); prms[0] = 10; prms[1] = 150; r = (int)typ.InvokeMember(„aMethod", BindingFlags.InvokeMethod, null, obj, prms);... }

20 Calling an Automation Server namespace AutomationClient { using EmotionalTulip; using System.Reflection;... TulipApplication tulipApp = new TulipApplication(); Type t = tulipApp.GetType(); Object[] prms = new Object[1]; prms[0] = true; t.InvokeMember("Visible", BindingFlags.SetProperty, null, tulipApp, prms); t.InvokeMember("Exit", BindingFlags.InvokeMethod, null, tulipApp, null);... }

21 Threading Most COM objects are single threaded.NET thread must initialize COM apartment Deferred initialization Initialized either as MTA or STA Runtime provides transparent use of COM threads Access apartment threaded objects through proxy Can avoid proxy by setting apartment state of thread

22 Let the runtime initialize the default MTA Setting ApartmentState explicitly eliminates proxy Do before the object is created! Using ApartmentState using System.Threading; using APTOBJLib; AptSimple obj = new AptSimple (); obj.Counter = 1; using System.Threading; using APTOBJLib; Thread.CurrentThread.ApartmentState = ApartmentState.STA; AptSimple obj = new AptSimple(); obj.Counter = 1;

23 Results and Exceptions COM reports errors via result code.NET methods throws exceptions Runtime manages transition HRESULT specifies exception class Extended information via IErrorInfo COM object should implement interface ErrorCode, HelpLink, Message Source, StackTrace, TargetSite PreserveSigAttribute in custom wrapper Suppresses translation to exception

24 Design for Interoperability Provide and register Type Libraries Use Automation Compliant Data Types Use Chunky Calls Marshalling may be costly Explicitly Free External Resources Avoid Using Members of System.Object Object, Equals, Finalize, GetHashCode, GetType MemberwiseClone and ToString

25 Restrictions and Limitations void* parameters need marshalling Success HRESULTS cannot be distinguished Failure HRESULT do raise exceptions Success code don‘t Typedef do not get through Variable length arrays cannot be imported is imported as HRESULT DoSomething(int cb, [in] byte buf[]); public void DoSomething(int cb, ref Byte buf);

26 Calling.NET Services from COM Use.NET class like COM class Type and methods must be public Early and late bound activation Convert Metadata to Type Library Wrapper of.NET component must be registered Can use RegAsm tool

27 COM Callable Wrappers Responsibilities of the COM Callable Wrapper Preserving Object Identity Maintaining object lifetime Proxying custom interfaces Marshalling method calls Synthezising selected interfaces COM Object CCW.NET Object IUnknown IDispatch IIfc

28 Identity and Lifetime Control Single CCW for.NET class insures identity No matter how many COM classes call to it No matter how object is created Each interface of the CCW is referenced counted No reference counting on the managed object Managed objects lives at least while the CCW lives But finalization is undeterministic Managed objects may occasionally leak Should be explicitly freed using CoEEShutDown

29 Synthesizing Selected Interfaces myClass implementing myItf derived from myBase _myClass : all methods of myItf, myBase, myClass _myBase : all methods of myBase myItf : all methods of myItf _Object Additional interfaces implemented on CCW IUnknown Standard implementation for lifetime management IDispatch Automation compatible or internal ITypeInfo, IProvideClassInfo, IErrorInfo

30 Exporting a Type Library Use SDK tool TlbExp Type library exported from assembly Use the TypeLibConverter Class Leave the conversion to RegAsm utility Export process involves a lot of conversions Name collisions are solved using name mangling tlbexp AssemblyName.dll /out:TlbFile

31 Sample Conversion public class MyClass { public void Write(string p, ref string q) {...}; public int GetInt() {...}; } [uuid(…), hidden, dual, odl, nonextensible, oleautomation] interface _MyClass : IDispatch { [propget] HRESULT ToString([out, retval] BSTR* pRetVal); HRESULT Equals([in] VARIANT obj, [out, retval] VARIANT_BOOL* pRetVal); HRESULT GetHashCode([out, retval] long* pRetVal ); HRESULT GetType([out, retval] _Type** pRetVal); HRESULT Write([in] BSTR p, [in, out] BSTR* q); HRESULT GetInt([out, retval] long* pRetVal); } [ uuid(...) ] coclass MyClass { [default] interface _MyClass; interface _Object; }

32 Special Attributes Attributes control the conversion process [In], [Out], [MarshalAs(...)] Parameters, Fields [GuidAttribute("...")] Assemblies, classes, interfaces, structures, enumerations, or delegates Uses Marshal.GenerateGuidForType function [ComVisibleAttribute(...)] Individual type or assembly level

33 Registration (RegAsm) Adds assembly information to the registry regasm assembly /tlb: tlbfile /regfile :regfile [HKCR\Namespace.Class] @=„Namespace.Class" [HKCR\Namespace.Class\CLSID] @="{...}" [HKCR\CLSID\{...}] @="Namespace.Class" [HKCR\CLSID\{...}\InprocServer32] @="C:\WINNT\System32\MSCorEE.dll" "ThreadingModel"="Both" "Class"="Namespace.Class" "Assembly"=„AssemblyName, Ver=1.0.0.0, Loc=""" [HKCR\CLSID\{...}\ProgId] @="Namespace.Class"

34 Results and Exceptions You know: COM uses HRESULTs,.NET exceptions Can‘t propagate exceptions to unmanaged code User defined exception classes define HRESULT Default is HRESULT of base class Class NoAccessException : public ApplicationException { NoAccessException() { HResult = E_ACCESSDENIED; } } CMyClass::MethodThatThrows { NoAccessException e = new NoAccessException(); throw e; }

35 Aggregation and Containment Simple requirements to be met Class must be public Class must have default constructor Containment: Simply create instance and delegate calls to it Aggregation Just use CoCreateInstance COM object‘s IUnknown as outer IUnknown Queries for unsupported interfaces are delegated back Reference counting is done on outer IUnknown

36 Exposing Inheritance Managed interfaces provide inheritance Always derive from IUnknown or IDispatch Interface inheritance is flattened Advantages with versioning Users of interfaces not effected when base changes Interfaces may be separately attributed Disadvantage Interfaces cannot be used polymorphically

37 Converted Inheritance Tree Original managed code interface IBase { void m1(); } interface IDrvd : IBase { void m2(); } class CDrvdImpl : IDrvd { void m1(); void m2(); } Converted type library interface IBase : IDispatch { void m1(); } interface IDrvd : IDispatch { void m2(); } interface _CDrvdImpl : IDispatch { boolean Equals(); // and other methods of object void m1(); void m2(); } coclass CDrvdImpl { interface IBase; interface IDerived; interface _CDerivedImpl; interface _Object; }

38 Restrictions and Limitations Parameterized constructors are not exposed Always uses default constructor Static methods are not exposed Wrapping with instance method required

39 Calling Platform Services from.NET Calling static functions in DLLs P/Invoke provides services Locates implementing DLL Loads DLL Finds function address Fuzzy name matching algorithm Pushes arguments on stack Performs marshalling Enables pre-emptive garbage collection Transfers control to unmanaged code

40 Code Sample namespace HelloWorld { using System; class MyClass { [dllimport(„user32.dll“, CharSet=CharSet.Ansi)] static extern int MessageBox(int h, string m, string c, int t); public static int Main() { return MessageBox(0, "Hello World!", "Caption", 0); } } }

41 Marshalling Strings are copied Converted to platform format: ANSI or Unicode Strings are never copied back – use StringBuilder Interfaces supported Cannot be used as out parameter Arrays of primitive types can be used Custom marshalling using attributes

42 Showcase for the Standard Marshaller int SomeFunc( int sel, void* buf, int size); [DllImport("some.dll")] static extern int SomeFunc(int sel, [MarshalAs(UnmanagedType.LPArray)] byte[] buf, int size); [ DllImport("some.dll", EntryPoint="SomeFunc")] static extern int SomeFunc_String(int sel, StringBuilder sb, int size); [DllImport("some.dll", EntryPoint="SomeFunc")] static extern int SomeFunc_Int(int sel, ref int i, int size); Given a method in some DLL Standard declaration may need special decoding May use taylored versions

43 Callbacks Unmanaged code can call back to managed code Unmanaged parameter is function pointer Must supply parameter as delegate P/Invoke creates callback thunk Passes address of thunk as callback parameter Managed Code.NET Application Call passes pointer to callback function Implementation of callback function Unmanaged Code DLL DLL function

44 Code Sample public class EnumReport { public bool Report(int hwnd, int lParam) { // report the window handle Console.Write("Window handle is "); Console.WriteLine(hwnd); return true; } }; public class SampleClass { delegate bool CallBack(int hwnd, int lParam); [DllImport("user32")] static extern int EnumWindows(CallBack x, int y); public static void Main() { EnumReport er = new EnumReport(); CallBack myCallBack = new CallBack(er.Report); EnumWindows(myCallBack, 0); } }

45 Security Suppressing demands for unmanaged code permission Calling class must be fully trusted Unmanaged code runs with no runtime checks Any code calling that class must be fully trusted [SuppressUnmanagedCodeSecurityAttribute()] [dllimport("some.dll")] private static extern int EntryPoint(args);

46 Component Services Fundamental building blocks Just-In-Time activation, synchronization, pooling Transaction processing, shared properties, etc. Mostly restricted to Windows 2000 COM+ generates and services context object.NET Client Context Object A Context Object B.NET Framework COM+ Services Object A (TX required) Object B (TX supported)

47 Using COM+ Services Derive class from System.ServicedComponent Add attributes to parameterize services Use attributes from Microsoft.ComServices namespace Helper classes: ContextUtil, RegistrationHelper Use regsvcs to register assembly as server Or rely on lazy registration

48 Transactions Sample using System; using System.Runtime.CompilerServices; using Microsoft.ComServices; [assembly:ApplicationName(“TestApp”)] [Transaction(TransactionOption.Required)] public class Account : ServicedComponent { [AutoComplete] public void Debit(int amount) { // Any exception thrown here aborts transaction // otherwise transaction commits } } class client { static int Main() { Account accountX = new Account(); accountX.Debit(100); return 0; } }

49 Summary Preserving investments and moving on Keep COM components and enhance using.NET Add managed components to COM projects Use Windows Component Services Prepare COM components for use with.NET.NET offers maximum transparency

50 Questions?


Download ppt "COM Interop & P/Invoke.NET and the Old World. Objectives Introduction to interoperation between.NET and COM COM and.NET.NET and platform services."

Similar presentations


Ads by Google