Notes
Slide Show
Outline
1
Using COM Objects
From .NET Framework Applications
2
Overview
  • How to use COM objects from .NET
  • The CLR’s support for COM and COM+
  • The cost of using COM objects from .NET


3
Using COM Types From .NET
  • Obtain a managed definition of the COM types
  • Primary Interop Assembly
    • Standard managed definition
    • First choice when available
  • Create your own (if necessary)
    • By adding references to the type library within Visual Studio
    • By using type library importer (TlbImp)
    • By defining types manually
4
Using COM Types From .NET
  • Reference the Interop Assembly when building projects
    • Done for you when adding reference in VS
    • Use /r: from command line compilers
      • CSC /t:library /r:MyLib.dll MyCode.cs
  • Use the types as managed types
    • Create instances with new
    • Catch exceptions
    • Even extend them

5
Data Type Conversion
Performed at Import
  • DATE     System.DateTime
  • BSTR     System.String
  • SafeArray(int)     int[]
  • interface IFoo     interface IFoo
  • coclass Bar     class BarClass +
  •                                          interface Bar
  • CURRENCY     System.Decimal
  • VARIANT     System.Object
  • IEnumVariant     IEnumerator
6
Imported Signature Translation

  • COM Method Signature


  • HRESULT FormatDate(BSTR s, DATE d, [out, retval] int *retval);




  • int FormatDate(String s, DateTime d);


  • .NET Method Signature
7
Model Transparency
  • Don’t think of types as COM types
    • No reference counting, No IDispatch
    • No HRESULTs.  No GUIDs
  • Sink events using managed eventing model
  • Cast to specific interfaces as necessary
    • InvalidCastException if QI fails
  • Failure HRESULTs are automatically mapped to exceptions
8
.Net to COM Object Support
Calling COM Components
9
Sample Code
  • public static void Main()
  • {
  • try
  • {
    • Excel.Application app = new Excel.Application();
    • app.Workbooks.Add(
    • Excel.XlWBATemplate.xlWBATWorksheet);
    • app.Visible = true;
    • app.UserControl = true;
    • }
    • catch (Exception)
    • {
    • Console.WriteLine("Error creating excel application!");
    • }
  • }
10
Installing Interop Assemblies
  • PIA should be provided by TLB publisher whenever possible
  • Interop Assemblies must be resolvable at runtime
    • Installed in Global Assembly Cache
      • Signed using TlbImp
        • TLBIMP MyLib.tlb keyfile:MyKey.snk
      • Installed in the GAC using
        • GACUTIL /i:MyLib.dll
    • Installed in Application directory
      • Copied to app directory
11
Late binding To COM Objects
No Import Required
  • public static void Main()
  • {
  • String progId = “Word.Application”;
  • Type t = Type.GetTypeFromProgID(progId);
  • Object o = Activator.CreateInstance(t);
  • t.InvokeMember("Visible",
  •   BindingFlags.SetProperty |
  • BindingFlags.Public |
  • BindingFlags.Instance,
  • null, o, new Object[] {true});
  • }
12
Late binding To COM Objects
From Visual Basic .NET
  • Public Shared Sub Main
  • Dim word As Object
  • word = CreateObject("Word.Application")
  • word.Visible = true
  • End Sub
13
 
14
Beyond The Basics
  • Output of TlbImp works without modifications for most type libraries
  • TlbImp has limitations
    • Success HRESULTs
    • C-Style arrays
    • Passing null to byref or out parameters
      • HRESULT Meth([out] int *pInt);
    • Multi dimensional SAFEARRAYs
    • Non-zero based SAFEARRAYs
15
Customizing Tlbimp Output
  • Command line options
    • /sysarray
    • /namespace
    • /asmversion
  • Using ILDasm/ILAsm
    • 1. tlbimp foo.tlb
    • 2. ildasm foo.dll /out:foo.il
    • 3. Edit the MSIL as required.
    • 4. ilasm foo.il
16
Sample
  • Preserve Signature
17
Defining COM Types Manually
  • Sometimes you need more control
    • Methods with complicated structures as arguments
    • Large TLB – only using a few classes
    • No type library
    • Parameter and return value marshalling
    • HRESULT behavior

18
Defining COM Types Manually
19
Primary Interop Assemblies
  • Standard managed definition of a COM type library
  • Should be provided by the vendor of the COM component
  • Must be strongly named
  • /primary tlbimp command line option
  • Are registered using regasm
20
GC Considerations
  • GC sees COM objects as smaller than they really are
    • GC isn’t aware of the unmanaged memory of the COM object
  • Use Marshal.ReleaseComObject to force the release of a COM object
  • Forcing the release can be required for some COM object models


21
Performance Considerations
  • Use STA threads to talk to STA components
  • Transitions have overhead
    • PInvoke: Roughly 10 instruction per call
    • COM Interop: Roughly 50 instruction per call
  • Data marshaling adds overhead
    • Depending on type and size of data
    • Blittable types are cheap
  • Use caching to avoid chatty calls
  • Consider rewriting existing code


22
Performance
23
Summary
  • It is really easy to use COM components from .NET
  • Any and all COM components can be used from .NET
  • For real world applications, Interop performance is quite good


24
Questions