Microsoft net framework interop
Download
1 / 58

Microsoft Framework Interop - PowerPoint PPT Presentation


  • 462 Views
  • Updated On :

Microsoft .NET Framework Interop. Brian Long Master Consultant Falafel Software. .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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Microsoft Framework Interop' - arne


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Microsoft net framework interop l.jpg

Microsoft .NETFramework Interop

Brian Long

Master Consultant

Falafel Software


Net interoperability l.jpg
.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


Interoperability options l.jpg
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)


Slide4 l.jpg
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


General points l.jpg
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)


Net com rcw l.jpg
.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)


Net com rcw7 l.jpg
.NET → COM (RCW)

  • Let’s make an Interop Assembly


Net com rcw8 l.jpg
.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


Net com rcw9 l.jpg
.NET → COM (RCW)

  • RCW manages COM object reference count

  • COM object is released during RCW garbage collection

  • RCW turns HRESULTs into .NET exceptions


Net com rcw10 l.jpg
.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


Net com rcw11 l.jpg
.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


Net com rcw12 l.jpg
.NET → COM (RCW)

  • Let’s see some RCW early binding


Net com rcw13 l.jpg
.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


Net com rcw14 l.jpg
.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)


Net com rcw15 l.jpg
.NET → COM (RCW)

  • Late binding:

  • Methods invoked through

    • System.Type.InvokeMember

  • Parameters passed in an object array


Net com rcw16 l.jpg
.NET → COM (RCW)

  • Let’s see some RCW late binding


Net com rcw17 l.jpg
.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


Net com rcw18 l.jpg
.NET → COM (RCW)

  • Let’s see some more RCW late binding


Net com rcw19 l.jpg
.NET → COM (RCW)

  • Let’s see RCW early binding with events


Com net ccw l.jpg
COM → .NET (CCW)

  • CCW – COM Callable Wrappers:COM wrapper around .NET object

  • Assembly registration utility (RegAsm.exe)


Com net ccw21 l.jpg
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)


Com net ccw22 l.jpg
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)


Com net ccw23 l.jpg
COM → .NET (CCW)

  • Let’s see some CCW late binding


Com net ccw24 l.jpg
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


Com net ccw25 l.jpg
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)


Com net ccw26 l.jpg
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


Com net ccw27 l.jpg
COM → .NET (CCW)

  • Let’s see some CCW early binding


Net win32 p invoke l.jpg
.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


Net win32 p invoke29 l.jpg
.NET → Win32 (P/Invoke)

  • Let’s see a traditional import


Net win32 p invoke30 l.jpg
.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;


Net win32 p invoke31 l.jpg
.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


Net win32 p invoke32 l.jpg
.NET → Win32 (P/Invoke)

  • Let’s see some P/Invoke imports


Net win32 p invoke33 l.jpg
.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


Net win32 p invoke34 l.jpg
.NET → Win32 (P/Invoke)

  • Let’s see P/Invoke imports in use


Net win32 p invoke35 l.jpg
.NET → Win32 (P/Invoke)

  • Other issues surround Win32 error codes:

    • DllImport.SetLastError

    • Marshal.GetLastWin32Error

    • GetLastError

  • HResult values:

    • safecall (Win32 COM)

    • DllImport.PreserveSig (.NET)


Net win32 p invoke36 l.jpg
.NET → Win32 (P/Invoke)

  • Let’s use P/Invoke attribute fields


Net win32 p invoke37 l.jpg
.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


Net win32 p invoke38 l.jpg
.NET → Win32 (P/Invoke)

  • Let’s see more P/Invoke code


Net win32 p invoke39 l.jpg
.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


Net win32 p invoke40 l.jpg
.NET → Win32 (P/Invoke)

  • Let’s see some VLI


Win32 net methods l.jpg
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


Win32 net methods42 l.jpg
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


Win32 net methods43 l.jpg
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


Win32 net methods44 l.jpg
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


Win32 net methods45 l.jpg
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


Win32 net methods46 l.jpg
Win32 → .NET methods

  • Let’s see some round tripping


Win32 net methods47 l.jpg
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


Win32 net methods48 l.jpg
Win32 → .NET methods

  • IL file assembly manifest (original):

    .module dotNetAssembly.dll

    .imagebase 0x00400000

    .subsystem 0x00000002

    .file alignment 512

    .corflags 0x00000001


Win32 net methods49 l.jpg
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


Win32 net methods50 l.jpg
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


Win32 net methods51 l.jpg
Win32 → .NET methods

  • Two IL methods (exported):

    .method public static void DoSomething(int32 I) cil managed

    {

    .vtentry 1:1

    .export [1] as DoSomething

    .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

    {

    .vtentry 1:2

    .export [2] as DoSomethingElse

    .maxstack 1

    IL_0000: ldarg.0

    // rest of code omitted for brevity

    } // end of method Unit::DoSomethingElse


Win32 net methods52 l.jpg
Win32 → .NET methods

  • Let’s see some creative round tripping


Win32 net methods53 l.jpg
Win32 → .NET methods

  • Potential maintenance issue: must modify IL generated from disassembling every built executable

  • Workaround is a utility to automate the process (perhaps a command-line utility)

  • One such utility (almost) is mme.exe (Managed Method Exporter)*

  • mme.exe is actually a simple GUI app

* supplied with source in the files that accompany this session


References l.jpg
References

Everything you ever wanted to know about COM Interop (and lots you didn’t):


References55 l.jpg
References

The book to have in order to learn about Delphi 8 and the Microsoft .NET Framework:


References56 l.jpg
References

Full coverage of CIL (or MSIL) by the author of ILASM, ILDASM & the CLR Metadata validation engine



Thank you l.jpg
Thank You

  • 3222

  • Microsoft .NET Framework Interop

  • Please fill out the speaker evaluation

  • You can contact me further at [email protected]


ad