COM Interop - PowerPoint PPT Presentation

1 / 50
About This Presentation
Title:

COM Interop

Description:

Access apartment threaded objects through proxy ... Typedef do not get through. Variable length arrays cannot be imported. is imported as ... – PowerPoint PPT presentation

Number of Views:242
Avg rating:3.0/5.0
Slides: 51
Provided by: achimo
Category:
Tags: com | interop

less

Transcript and Presenter's Notes

Title: COM Interop


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

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 Object2 int r
typ Type.GetTypeFromProgID(MyLib.MyServer")
obj Activator.CreateInstance(typ) prms0
10 prms1 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
Object1 prms0 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
Using ApartmentState
  • Let the runtime initialize the default MTA
  • Setting ApartmentState explicitly eliminates
    proxy
  • Do before the object is created!

using System.Threadingusing APTOBJLib AptSimple
obj new AptSimple () obj.Counter 1
using System.Threading using APTOBJLib Thread.C
urrentThread.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 dont
  • 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

IUnknown
IIfc
COM Object
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 /outTlbFile
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 /tlbtlbfile /regfileregfile

HKCR\Namespace.Class _at_Namespace.Class" HKCR\N
amespace.Class\CLSID _at_"..." HKCR\CLSID\...
_at_"Namespace.Class" HKCR\CLSID\...\InprocServe
r32 _at_"C\WINNT\System32\MSCorEE.dll" "Threadin
gModel""Both" "Class""Namespace.Class" "Assemb
ly"AssemblyName, Ver1.0.0.0,
Loc""" HKCR\CLSID\...\ProgId
_at_"Namespace.Class"
34
Results and Exceptions
  • You know COM uses HRESULTs, .NET exceptions
  • Cant 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
CMyClassMethodThatThrows
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 objects 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,
CharSetCharSet.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
  • Given a method in some DLL
  • Standard declaration may need special decoding
  • May use taylored versions

int SomeFunc( int sel, void buf, int
size) DllImport("some.dll")static extern
int SomeFunc(int sel, MarshalAs(UnmanagedType.LP
Array) 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)
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

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

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 Systemusing System.Runtime.CompilerService
susing Microsoft.ComServices assemblyApplicat
ionName(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?
Write a Comment
User Comments (0)
About PowerShow.com