com interop p invoke
play

COM Interop & P/Invoke .NET and the Old World Objectives - PowerPoint PPT Presentation

COM Interop & P/Invoke .NET and the Old World Objectives Introduction to interoperation between .NET and COM COM and .NET .NET and platform services Contents Section 1: Overview Section 2: Calling COM Services from


  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 COMLib.COMClass COMLib.COMClass aCOMObject; aCOMObject; aCOMObject aCOMObject = new = new COMLib.COMClass; COMLib.COMClass; � Metadata must be available at compile time � Must be referenced in development environment � At runtime, Metadata and COM library must be available

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

  9. Consuming Selected Interfaces � ISupportErrorInfo ISupportErrorInfo � Additional information with exceptions � IProvideClassInfo IProvideClassInfo � Typed wrapper � ITypeInfo ITypeInfo TlbImp converts references to System.Type � TlbImp 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 COMLib.COMClass aCOMObject; aCOMObject; aCOMObject aCOMObject = new = new COMLib.COMClass(); COMLib.COMClass(); aCOMObject.SomeFunc(); aCOMObject.SomeFunc(); Marshal.ReleaseComObject(aCOMObject); 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: IDL: [custom(„FE42746F-...-AC...84178”, “Value”)] [custom(„FE42746F-...-AC...84178”, “Value”)] .NET: .NET: [IdlAttribute(„FE42746F-...-AC...84178”, “Value”)] [IdlAttribute(„FE42746F-...-AC...84178”, “Value”)]

  12. Conversions by TlbImp 1/2 � Library level � Library to namespace library library COMLib { COMLib { namespace namespace COMLib { COMLib { interface Widget {}; interface Widget {}; interface Widget {}; interface Widget {}; coclass coclass Slingshot {}; Slingshot {}; class Slingshot {}; class Slingshot {}; } } custom(0F21F359-AB84-41e8-9A78-36D110E6D2F9, custom(0F21F359-AB84-41e8-9A78-36D110E6D2F9, „MyNamespace.Class") „MyNamespace.Class") � Module is converted to class � Constants within module to constants within that class � Module functions to static members of the 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 get and set set � Events namespace namespace COMLib { COMLib { interface Widget {}; interface Widget {}; class Slingshot {}; 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 � StructLayout Sequential layout – is a regular structure � Sequential � Default Union Union layout Explicit layout � Explicit [StructLayout(Layout.Explicit)] [StructLayout(Layout.Explicit)] public class SYSTEM_INFO public class SYSTEM_INFO { { [FieldOffset(0)] ulong [FieldOffset(0)] ulong OemId; OemId; [FieldOffset(4)] ulong [FieldOffset(4)] ulong PageSize; PageSize; [FieldOffset(16)] ulong [FieldOffset(16)] ulong ActiveProcessorMask; ActiveProcessorMask; [FieldOffset(20)] ulong [FieldOffset(20)] ulong NumberOfProcessors; NumberOfProcessors; [FieldOffset(24)] ulong [FieldOffset(24)] ulong ProcessorType; 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 namespace CallingCOMServer { using System; using System; using COMServerLib; using COMServerLib; public class DotNET_COMClient public class DotNET_COMClient {... {... public static int Main(string[] args) public static int Main(string[] args) { MyCOMServer myS MyCOMServer myS = new MyCOMServer(); = new MyCOMServer(); return return (myS.Add (myS.Add (17,4)); (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 � InvokeMember � Metadata is not needed, but useful � COM object is wrapped by __ComObject

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

  20. Calling an Automation Server namespace AutomationClient namespace AutomationClient { using EmotionalTulip; using EmotionalTulip; using System.Reflection; using System.Reflection; ... ... TulipApplication tulipApp = new TulipApplication(); TulipApplication tulipApp = new TulipApplication(); Type t Type t = tulipApp.GetType(); tulipApp.GetType(); Object[] prms Object[] prms = new Object[1]; = new Object[1]; prms[0] = true; prms[0] = true; t.InvokeMember("Visible", t.InvokeMember("Visible", BindingFlags.SetProperty, BindingFlags.SetProperty, null, tulipApp, prms); null, tulipApp, prms); t.InvokeMember("Exit", t.InvokeMember("Exit", BindingFlags.InvokeMethod, BindingFlags.InvokeMethod, null, tulipApp, null); 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. Using ApartmentState � Let the runtime initialize the default MTA using System.Threading; using System.Threading; using APTOBJLib; using APTOBJLib; AptSimple AptSimple obj obj = new AptSimple = new AptSimple (); (); obj.Counter obj.Counter = 1; = 1; � Setting ApartmentState explicitly eliminates proxy � Do before the object is created! using System.Threading; using System.Threading; using APTOBJLib; using APTOBJLib; Thread.CurrentThread.ApartmentState Thread.CurrentThread.ApartmentState = = ApartmentState.STA; ApartmentState.STA; AptSimple AptSimple obj obj = new AptSimple(); = new AptSimple(); obj.Counter obj.Counter = 1; = 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 HelpLink , Message � ErrorCode Message Source , StackTrace StackTrace , TargetSite � Source TargetSite PreserveSigAttribute in custom wrapper � PreserveSigAttribute � 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

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend