Microsoft .NET Framework Interop - PowerPoint PPT Presentation

microsoft net framework interop n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Microsoft .NET Framework Interop PowerPoint Presentation
Download Presentation
Microsoft .NET Framework Interop

play fullscreen
1 / 58
Microsoft .NET Framework Interop
509 Views
Download Presentation
arne
Download Presentation

Microsoft .NET Framework Interop

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Microsoft .NETFramework Interop Brian Long Master Consultant Falafel Software

  2. .NET Interoperability • Why Interoperability? • The .NET platform is new • The Win32 platform is well established • No one wants to start from scratch • Use of existing code in .NET applications is essential • Interoperability goes both ways

  3. Interoperability Options • .NET clients can use: • Win32 COM server objects (RCW) • Win32 DLL exports (P/Invoke) • Win32 COM clients can use: • .NET objects (CCW) • Win32 clients can use: • .NET method exports (Inverse P/Invoke)

  4. COM • COM is dead!!! • COM code equals legacy code • If you don’t know COM, don’t start learning it now • Er, .... • That’s not practical • There is a massive investment in COM that we still need to use

  5. General Points • COM ↔ .NET Interoperability is usually called Com Interop • COM/Win32 ↔ .NET requires marshaling of parameters • COM Interop requires some reconciliation of COM reference counting and .NET GC mechanisms • Interoperability requires some proxy / thunk / wrapper to be in place (automated)

  6. .NET → COM (RCW) • RCW – Runtime Callable Wrappers:.NET wrapper around COM object • Type library importer (TlbImp.exe) generates an Interop Assembly • Delphi 8 & “Diamondback” IDEs do it just as well • Interop Assemblies have a common naming convention: Interop.LibraryName.dll(LibraryName is the type library name, not the COM server name)

  7. .NET → COM (RCW) • Let’s make an Interop Assembly

  8. .NET → COM (RCW) • Use Primary Interop Assembly if available • Primary Interop Assemblies are provided and signed by the COM component’s creator • E.g. adodb.dll for MDAC objects • Microsoft Office XP Primary Interop Assemblies available from MSDN web site

  9. .NET → COM (RCW) • RCW manages COM object reference count • COM object is released during RCW garbage collection • RCW turns HRESULTs into .NET exceptions

  10. .NET → COM (RCW) • A coclass Foo becomes an RCW FooClass • Interfaces keep the same name • An additional interface Foo is generated, combining the coclass’ default interface and a helper interface for the default event interface • An event method Bar from an event interface IEvents gets turned into a delegate type IEvents_BarEventHandler. • These COM events can be hooked up like normal .NET events

  11. .NET → COM (RCW) • Early binding: • Straightforward - get an interface reference from the construction of the RCW • Call methods or access properties • Exposed events can be set up just like normal .NET events

  12. .NET → COM (RCW) • Let’s see some RCW early binding

  13. .NET → COM (RCW) • If the type library importer does not provide appropriate parameter type marshaling you can tweak it using creative round tripping • Little other choice exists

  14. .NET → COM (RCW) • Late binding: • This is possible without the Interop Assembly • Uses reflection to operate • New instance (CreateOleObject) through: • System.Type.GetTypeFromProgID • Activator.CreateInstance • Current instance (GetActiveOleObject) through: • Marshal.GetActiveObject • Note System.Reflection.Missing and System.Type.Missing (for EmptyParam)

  15. .NET → COM (RCW) • Late binding: • Methods invoked through • System.Type.InvokeMember • Parameters passed in an object array

  16. .NET → COM (RCW) • Let’s see some RCW late binding

  17. .NET → COM (RCW) • Late binding: • Reference parameters are fiddly • Overloaded InvokeMember requires single element array of ParameterModifier • ParameterModifier is an array of Boolean flags • Flag is True for reference parameter • Flag is False for value parameter

  18. .NET → COM (RCW) • Let’s see some more RCW late binding

  19. .NET → COM (RCW) • Let’s see RCW early binding with events

  20. COM → .NET (CCW) • CCW – COM Callable Wrappers:COM wrapper around .NET object • Assembly registration utility (RegAsm.exe)

  21. COM → .NET (CCW) • CCW ensures it will be marked for garbage collection when external reference count reaches 0 • CCW turns .NET exceptions into HRESULTs • Assembly must be accessible to CLR: • installed in GAC • resident in application directory (or available for probing)

  22. COM → .NET (CCW) • Late binding simply requires the assembly to be registered • Late binding uses a ProgID registered by RegAsm.exe: AssemblyName.ClassName(e.g. MyAssembly.MyClass)

  23. COM → .NET (CCW) • Let’s see some CCW late binding

  24. COM → .NET (CCW) • Early binding relies on an Interop Type Library: • use the /tlb option with RegAsm • use the import wizard in “Diamondback” • .NET objects may choose to implement a defined interface or not • The Guid attribute can be used to give a .NET interface an IID (traditional Delphi syntax should also work*) • * And does in “Diamondback”, but not in Delphi 8

  25. COM → .NET (CCW) • The ClassInterface attribute controls whether and how an interface will be manufactured to expose the class: • AutoDispatch - dispinterface for late binding (the default) • AutoDual – for early binding (versioning issues)interface is class name with _ prefix • None – IDispatch access only • Use AutoDual if you have no interface • Use None if you implement an interface (the suggested approach to avoid interface versioning issues)

  26. COM → .NET (CCW) • Importing a Delphi assembly’s Interop Type Library requires some forethought, due to the symbols exposed by default • Use [assembly: ComVisible(False)] and [ComVisible(True)] to control default visibility • Early binding from Win32 uses the creator class in the type library import unit, as usual, or any of the other standard options

  27. COM → .NET (CCW) • Let’s see some CCW early binding

  28. .NET → Win32 (P/Invoke) • Platform Invocation Service, usually referred to as Platform Invoke, or simply P/Invoke (or even PInvoke): • DllImport attribute (from System.Runtime.InteropServices) is needed for routines with text parameters • Standard Delphi DLL import syntax works otherwise • Uses DllImport behind the scenes • Caveat is string parameters

  29. .NET → Win32 (P/Invoke) • Let’s see a traditional import

  30. .NET → Win32 (P/Invoke) • //Win32 • procedure FooA(Msg: PChar); cdecl; • begin • MessageBox(0, Msg, 'Foo', MB_OK or MB_ICONQUESTION); • end; • //.NET • procedure Foo(const Msg: String); • ... • [DllImport('bar.dll', • EntryPoint = 'FooA', • CharSet = CharSet.Ansi, • CallingConvention = • CallingConvention.Cdecl)] • procedure Foo(const Msg: String); external;

  31. .NET → Win32 (P/Invoke) • The big issue with P/Invoke is ensuring the parameters are marshaled across correctly. • String parameters are generally catered for with DllImport.CharSet: • Ansi • None • Unicode • Auto* *uses Ansi on Win9x and Unicode on NT platforms

  32. .NET → Win32 (P/Invoke) • Let’s see some P/Invoke imports

  33. .NET → Win32 (P/Invoke) • Use Windows.pas and Delphi.Vcl.Windows.pas as guidelines for parameter type translation • MarshalAs parameter attribute from System.Runtime.InteropServices • Used to fix parameter marshaling when the default marshaling is inappropriate

  34. .NET → Win32 (P/Invoke) • Let’s see P/Invoke imports in use

  35. .NET → Win32 (P/Invoke) • Other issues surround Win32 error codes: • DllImport.SetLastError • Marshal.GetLastWin32Error • GetLastError • HResult values: • safecall (Win32 COM) • DllImport.PreserveSig (.NET)

  36. .NET → Win32 (P/Invoke) • Let’s use P/Invoke attribute fields

  37. .NET → Win32 (P/Invoke) • Performance: • P/Invoke calls cost ~10 machine instructions • Cost rises for each extra job (marshaling etc.) • By default security is on • UnmanagedCode permission • SuppressUnmanagedCodeSecurity attribute omits security check stack walk

  38. .NET → Win32 (P/Invoke) • Let’s see more P/Invoke code

  39. .NET → Win32 (P/Invoke) • New in Delphi “Diamondback” • Virtual Library Interfaces (VLI) aka Dynamic PInvoke • Makes a set of functions implemented in a DLL look like an interface implemented by an object • Uses new overload of Supports

  40. .NET → Win32 (P/Invoke) • Let’s see some VLI

  41. Win32 → .NET methods • Little known mechanism (Inverse P/Invoke), primarily discussed in: • Inside Microsoft .NET IL Assembler, Serge Lidin, Microsoft Press • Uses method transition thunks • Only supported by Managed C++ and IL • Oh, and Delphi for .NET

  42. Win32 → .NET methods • Very trivial mechanism in Delphi: managed exports • Simply use an exports clause as you do in Win32 when exporting functions from DLLs • Caveats: • Must mark the project source as containing unsafe code: {$UNSAFECODE ON} • Can only export “global” routines • Can not export static class methods this way

  43. Win32 → .NET methods • Can also be accomplished in other languages • Much more involved (as indeed it is when exposing Delphi static class methods) • Involves creative round-tripping to expose assembly methods

  44. Win32 → .NET methods • Round-tripping: • Disassemble a compiled assembly to an IL source file with the .NET disassembler: ildasm.exe • Modify the IL code, or add additional IL files, possibly to include features not supported by the original compiler • Reassemble the IL code with the .NET assembler: ilasm.exe

  45. Win32 → .NET methods • Creative round-tripping: • Disassemble a compiled assembly to an IL source file with the .NET disassembler: ildasm.exe • Modify the IL code, or add additional IL files, possibly to include features not supported by the original compiler • Reassemble the IL code with the .NET assembler: ilasm.exe

  46. Win32 → .NET methods • Let’s see some round tripping

  47. Win32 → .NET methods • IL modifications to export .NET methods: • Modify IL manifest: • Modify .corflags directive to cater for XP issue • Declare a v-table fixup table • Declare data space for the v-table fixup table • Modify implementations of methods to be exported: • Mark each method with the .vtentry and .export directives

  48. Win32 → .NET methods • IL file assembly manifest (original): .module dotNetAssembly.dll .imagebase 0x00400000 .subsystem 0x00000002 .file alignment 512 .corflags 0x00000001

  49. Win32 → .NET methods • IL file assembly manifest (modified): .module dotNetAssembly.dll .imagebase 0x00400000 .subsystem 0x00000002 .file alignment 512 .corflags 0x00000002 .data VT_01 = int32[2] .vtfixup [2] int32 fromunmanaged at VT_01

  50. Win32 → .NET methods • Two IL methods (original): .method public static void DoSomething(int32 I) cil managed { .maxstack 1 IL_0000: ldarg.0 // rest of code omitted for brevity } // end of method Unit::DoSomething .method public static void DoSomethingElse([in] string Msg) cil managed { .maxstack 1 IL_0000: ldarg.0 // rest of code omitted for brevity } // end of method Unit::DoSomethingElse