Type Library to Assembly 转换摘要

Type Library to Assembly 转换摘要

COM_style type library ==> .NET Framework metadata.
The .NET Framework provides both tools and an API to perform type library to

assembly conversion. Although you have several mechanisms for generating an

assembly from a type library, each produces the same results. For simplicity, this

section describes only the Type Library Importer (Tlbimp.exe) tool in conjunction

with the conversion rules for importing type information. 

$1、Imported Library Conversion
(Describes how the import process converts type library information. )

When the import process converts a type library, it automatically places the types

defined within the library in a namespace of the same name as the type library.

For example, if you run Tlbimp.exe on the following type library, the utility

imports all types defined within the AcmeLib type library into the AcmeLib

namespace.

library AcmeLib {
    interface Widget {};
    coclass Slingshot {};
}; 
==>
namespace AcmeLib {
    interface Widget {};
    class Slingshot {};
};
可以通过以下技术实现命名空间的重命名(和原来类型库名不一样)。
[
    uuid(...),
    version(1.0),
    custom(0F21F359-AB84-41e8-9A78-36D110E6D2F9, "Acme.WidgetLib")  //Here is it!
]
library AcmeLib {
    interface Widget {};
    coclass Slingshot {};
};
By using the user-defined attribute, you can force Tlbimp.exe to import the

AcmeLib type library into the Acme.WidgetLib namespace. The Slingshot class

becomes Acme.WidgetLib.Slingshot in managed code.

$2、Imported Module Conversion
(Describes how the import process converts modules containing the definitions of

constants and methods. )

A type library can have one or more modules containing the definitions of

constants and methods. Constants defined within modules are imported as public

constant static members of a class with the same name as the original module.

Constants defined outside of a module are not imported.

[
    uuid(12345678-1234-1234-1234-123456789ABC), 
]
library TestConstants
{
    [
        uuid(12345678-1234-1234-1234-123456789ABC), 
        dllname("test.dll")
    ]
    module Constants
    {
        const short FRAME_COLOR = 0x10;
        const short WINDOW_COLOR = 0x20;
        const short BUTTON_COLOR = 0x40;
        ...
    };
};
==>  Converted types appear as follows:
public class Constants
{
    public const short FRAME_COLOR = 0x10;
    public const short WINDOW_COLOR = 0x20;
    public const short BUTTON_COLOR = 0x40;
}

$3、Imported Type Conversion
(Describes how the import process converts interfaces, classes, structures,

enumerations, constants, and typedefs. )

This topic describes how the import process converts the following types:

Interfaces
Classes
Structures
Enumerations
Constants
Typedefs

In general, Tlbimp.exe imports types with the same name they had in the original

type library. Names within a type library must be unique, thereby eliminating

naming conflicts during the conversion process. All valid type-library names are

valid assembly names.

Imported types are scoped by the namespace to which they belong, which is the same

as the original type library. Types are individually identified by their complete

namespace and type names.

You can explicitly control the managed name of an imported type by using a type

library attribute in the type library. This user-defined attribute identifier is

0F21F359-AB84-41e8-9A78-36D110E6D2F9. The following type library shows the

addition of the user-defined attribute.

Type library representation:
[  uuid(...),
    version(1.0)
]
library AcmeLib {
    interface Widget {};
    [custom(0F21F359-AB84-41e8-9A78-36D110E6D2F9,
     "Acme.WidgetLib.Slingshot")]
    coclass Slingshot {};
};

Even though Tlbimp.exe imports the type library into the AcmeLib namespace, the

Slingshot class becomes Acme.WidgetLib.Slingshot.

Interfaces
When the import process converts an interface, it strips out all IUnknown and

IDispatch methods. The conversion applies the GuidAttribute to the interface to

retain the interface identifier (IID) assigned in the type library and the

InterfaceTypeAttribute unless the interface is dual (an interface deriving from

IDispatch).

Type library representation:
[uuid(...), ]
interface IWidget : IUnknown {
    HRESULT New()
    HRESULT Start()
};
[uuid(...), ]
interface IGadget : IWidget {
    HRESULT Baz()
};
==>
During conversion, the import process adds the methods of the base interface to

the derived interface. In the following example, New and Start are added to the

IGadget interface:

[Guid(...), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IWidget {
    void New();
    void Start();
};
[Guid(...), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IGadget : IWidget {
    new void New();
    new void Start();
    void Baz();
};

Classes
The import process creates a managed class to represent each COM coclass, giving

the managed class the same name as the original coclass appended with Class. For

example, the NewNewer coclass becomes NewNewerClass. The conversion adds the

GuidAttribute to the class to capture the class identifier (CLSID) of the coclass.

In addition to the managed class, the import process adds an interface with the

same name as the coclass and applies the CoClassAttribute to identify the CLSID of

the original coclass. This interface has the same IID as the default interface for

the coclass. With this interface, clients can always register as event sinks.

Unlike a COM coclass, a managed class can contain class members. In keeping with

the .NET Framework approach, the conversion adds to each class the members

associated with each interface implemented by the coclass. Users of the managed

class can invoke methods and properties of the managed type without first casting

to a specific interface. The import process also adds a default constructor to

each converted coclass. A constructor makes it possible to create the class from

managed code. (Classes without a constructor cannot be created). The default

constructor has no arguments; its implementation calls the base class constructor.

If the noncreatable type library attribute is applied to the coclass, the import

process does not create a default constructor for the class.

Since interface member names are not always unique, name and DispId collisions

among members can occur. TlbImp.exe resolves name collisions by prefixing the

interface name and an underscore to the name of each colliding member of the

class. Where the names of members collide, the first interface listed in the

coclass statement remains unchanged.

When DispId collisions occur, the import process assigns DispIds to members of the

coclass's default interface and none to the conflicting class members. However,

the import process always assigns DispIds to members of the interface.

Type library representation:
[uuid(...)]
interface INew : IDispatch {
    [id(0x100)] HRESULT DoFirst();
    [id(0x101)] HRESULT DoSecond();
}
[uuid(...)]
interface INewer : IDispatch {
    [id(0x100)] HRESULT DoNow();
    [id(0x101)] HRESULT DoSecond();
}
[uuid(...)]
coclass NewNewer  {
    [default] interface INew;
    interface INewer;
}
==>
The converted types appear as follows:
[Guid(...)]
public interface INew {...}

[Guid(...)]
public interface INewer {...}

[Guid(...)]
public interface NewNewer : INew {...}

[Guid(...)]
public class NewNewer : INew, INewer, NewNewer{
// Method implementation.
     [DispId(100)]...
}
Structures
Structures defined within a type library are imported as metadata. If a field of a

struct is a reference type, Tlbimp.exe imports the type as an IntPtr and applies

the ComConversionLossAttribute. The attribute indicates that information was lost

during the import process.

Enumerations
Type Library Importer (Tlbimp.exe) imports unmanaged enumerations as managed Enum

types.

Constants
Constants will not be imported from type library in this release.

Typedefs
Type definitions (typedefs) within a type library are not imported. Instead,

parameters and fields are imported as the underlying types. For example, a

parameter of type BUTTON_COLOR is imported as type integer, since BUTTON_COLOR is

an alias for an integer.

Once imported, parameters and fields carry information that associates them with

their original type in the ComAliasNameAttribute. The conversion process applies

ComAliasNameAttribute to associate a field, parameter, or return value with the

name of the type library and the type within the library that was used as an

alias.

The following type library representation shows that the cl parameter is typed as

a BUTTON_COLOR, which is an alias for an integer.

Type library representation

library MyLib {
    typedef [public] int BUTTON_COLOR;

    interface ISee {
        HResult SetColor([in] BUTTON_COLOR cl);
        HResult GetColor([out, retval] BUTTON_COLOR *cl);
    };
  
    coclass See {
        [default] interface ISee
    };
};
==>
The converted types appear as follows:
public interface ISee {
    void SetColor([ComAliasName("MyLib.BUTTON_COLOR")]] int cl);
    [return: ComAliasName("MyLib.BUTTON_COLOR")] int GetColor();
};

public class See {
    public void SetColor([ComAliasName("MyLib.BUTTON_COLOR")]] int cl);
    [return: ComAliasName("MyLib.BUTTON_COLOR")] int GetColor();
};

Note that the actual type BUTTON_COLOR is not defined in the resulting metadata.

Instead, the parameters typed as BUTTON_COLOR in the type library are typed as the

underlying type, int, and are attributed with the ComAliasNameAttribute. This

conversion process also applies the attribute to arguments on class methods.

$4、Imported Member Conversion
(Describes how the import process converts methods, properties, and events.)

This topic describes how the import process converts the following members:

Methods
Properties
Events
Tlbimp.exe applies the DefaultMemberAttribute to any method or property with a

DispID of 0. Note that C# developers must treat these members as arrays. For

additional information, see your programming language documentation.

Methods
When COM interop imports a COM type, it produces a .NET Framework method signature

equivalent to the original COM method signature. During the conversion process, it

maps COM parameters, return values, and HRESULTs to those in a .NET Framework

method signature, as shown in the following illustration.

Method signature conversion

You can examine method syntax with an object viewer or by using reflection, just as with any other .NET class. By default, when the COM object returns a failure HRESULT, the runtime throws a corresponding exception.


 

原文地址:https://www.cnblogs.com/MayGarden/p/1630004.html