zoukankan      html  css  js  c++  java
  • C#如何调用COM

    这章中描述的属性被用在创建和COM程序交互的程序中。

    1.1  COMImport 属性

    当被放在一个类上, COMImport 属性就把这个类标记为一个外部实现的COM 类。这样的一个类声明使得可以用一个C# 名称调用一个COM 类。

    1 namespace System.Runtime.InteropServices
    2 {
    3 [AttributeUsage(AttributeTargets.Class)]
    4 public class COMImportAttribute: System.Attribute
    5 {
    6      public COMImportAttribute() {…}
    7 }
    8 }

    用COMImport 属性修饰的类要受下面的限制:

    • 它必须也被Guid 属性修饰,它为被引入的COM类指定了CLSID 。如果一个类声明包含COMImport 属性,但是没有包含Guid 属性,就会发生一个编译时错误。
    • 它不能有任何成员。(一个没有参数的公共构造函数会被自动提供。)
    • 他必须从object类派生。

    示例

    1 using System.Runtime.InteropServices;
    2 [COMImport, Guid("00020810-0000-0000-C000-000000000046")]
    3 class Worksheet {}
    4 class Test
    5 {
    6 static void Main() {
    7      Worksheet w = new Worksheet();  // Creates an Excel worksheet
    8 }
    9 }

    声明了一个类Worksheet ,这个类作为一个类从有CLSID “00020810-0000-0000-C000-000000000046″的COM引入。一个Worksheet 实例的实例化造成了一个相应的COM实例化。

    1.2 COMRegisterFunction 属性

    一个方法中的COMRegisterFunction 属性的实现,指示出这个方法应该在COM注册过程中被调用。

    1 namespace System.Runtime.InteropServices
    2 {
    3 [AttributeUsage(AttributeTargets.Method)]
    4 public class COMRegisterFunctionAttribute: System.Attribute
    5 {
    6      public ComRegisterFunctionAttribute() {…}
    7 }
    8 }

    1.3 COMSourceInterfaces 属性

     COMSourceInterfaces 属性用来列出引入的联合类中的源接口。

    1 namespace System.Runtime.InteropServices
    2 {
    3 [AttributeUsage(AttributeTargets.Class)]
    4 public class ComSourceInterfacesAttribute: System.Attribute
    5 {
    6      public ComSourceInterfacesAttribute(string value) {…}
    7      public string Value { get {…} }
    8 }
    9 }

    1.4 COMVisible 属性

    COMVisible 属性用来指定一个类或接口在COM中是否可见。

    1 namespace System.Runtime.InteropServices
    2 {
    3 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
    4 public class COMVisibleAttribute: System.Attribute
    5 {
    6      public COMVisibleAttribute(bool value) {…}
    7      public bool Value { get {…} }
    8 }
    9 }

    1.5 DispId 属性

    DispId 属性被用来指定一个OLE 的自动化 DISPID。一个DISPID 是一个整数类型数值,它在dispinterface中指定一个成员。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
    public class DispIdAttribute: System.Attribute
    {
         public DispIdAttribute(int value) {…}
         public int Value { get {…} }
    }
    }

    1.6 DllImport 属性

    DllImport 属性用来指定包含一个外部方法的实现程序的dll的位置。

     1 namespace System.Runtime.InteropServices
     2 {
     3 [AttributeUsage(AttributeTargets.Method)]
     4 public class DllImportAttribute: System.Attribute
     5 {
     6      public DllImportAttribute(string dllName) {…}
     7      public CallingConvention CallingConvention;
     8      public CharSet CharSet;
     9      public string EntryPoint;
    10      public bool ExactSpelling;
    11      public bool SetLastError;
    12      public bool TransformSig;
    13      public string Value { get {…} }
    14 }
    15 }

    特别地, DllImport 属性友下面的行为:

    • 它只能用在方法声明中。
    • 它有一个位置参数: dllName 参数,指定包含要引入的方法的dll的名称。
    • 他有五个名称参数:
    • 它是一个单次使用属性类。
    • CallingConvention 参数指定为入口点调用的转换。如果没有指定CallingConvention ,默认的CallingConvention.Winapi 就会被使用。
    • CharSet 参数指定用于入口点的字符集。如果没有CharSet 被指定,就会使用默认的CharSet.Auto。
    • EntryPoint 参数给出dll中的入口点的名称。如果没有EntryPoint 被指定,就会使用方法自己的名称。
    • ExactSpelling 参数指定是否EntryPoint 必须与指出的入口点的拼写相匹配。如果没有指定ExactSpelling ,就会使用默认得false。
    • SetLastError 参数指出方法是否保存Win32 的”最后的错误”。如果没有指定SetLastError ,就会使用默认的false。
    • TransformSig 参数指出是否要为返回数值把方法的签名转换为一个有HRESULT 返回值和有附加的外部参数的称为retval量的返回数值。如果没有指定TransformSig 数值,就会使用默认得false。

    另外,一个被DllImport 属性修饰的方法必须有extern 修饰符。

    1.7 FieldOffset 属性

    FieldOffset 属性被用来为结构指定域的规划。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Field)]
    public class FieldOffsetAttribute: System.Attribute
    {
         public FieldOffsetAttribute(int value) {…}
         public int Value { get {…} }
    }
    }

    FieldOffset 属性也许不会被放在一个作为类的成员的域声明中。

    1.8 GlobalObject 属性

    GlobalObject 属性的存在指定一个类是COM中的”全局” 或 ”appobject” 类。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Class)]
    public class GlobalObjectAttribute: System.Attribute
    {
         public GlobalObjectAttribute() {…}
    }
    }

    1.9 Guid 属性

    Guid 属性用来为一个类或一个接口指定一个全局的唯一标识符 (GUID)。这个信息主要用于与COM的互用性中。

     1 namespace System.Runtime.InteropServices
     2 {
     3 [AttributeUsage(AttributeTargets.Class
     4                    | AttributeTargets.Interface
     5                    | AttributeTargets.Enum
     6                    | AttributeTargets.Delegate
     7                    | AttributeTargets.Struct)]
     8 public class GuidAttribute: System.Attribute
     9 {
    10      public GuidAttribute(string value) {…}
    11      public string Value { get {…} }
    12 }
    13 }

    位置字符串参数的形式在编译时被验证。指定一个在不是句法上有效的GUID的字符串参数是错误的。

    1.10 HasDefaultInterface 属性

    如果存在, HasDefaultInterface 属性指出一个类游一个默认接口。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Class)]
    public class HasDefaultInterfaceAttribute: System.Attribute
    {
         public HasDefaultInterfaceAttribute() {…}
    }
    }

    1.11  ImportedFromTypeLib 属性

    ImportedFromTypeLib 属性被用来指定一个模块从COM类型库中被引入。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Module)]
    public class ImportedFromTypeLib: System.Attribute
    {
         public ImportedFromTypeLib(string value) {…}

         public string Value { get {..} }

    }
    }

    1.12 In 和 Out 属性

    In 和 Out 属性被用来为参数提供自定义集合信息。这些集合属性的所有组合都是允许的。

     1 namespace System.Runtime.InteropServices
     2 {
     3 [AttributeUsage(AttributeTargets.Parameter)]
     4 public class InAttribute: System.Attribute
     5 {
     6      public InAttribute() {…}
     7 }
     8 [AttributeUsage(AttributeTargets.Parameter)]
     9 public class OutAttribute: System.Attribute
    10 {
    11      public OutAttribute() {…}
    12 }
    13 }

    如果一个参数没有被任何集合属性修饰,那么它就是基于它的参数修饰符,就像下面一样。如果参数没有修饰符,那么集合是 [In]。 如果参数有ref 修饰符,那么集合是 [In, Out]。 如果参数有out修饰符,那么集合是 [Out]。

    注意out是一个关键字,而Out是一个属性。示例

    1 class Class1
    2 {
    3 void M([Out] out i, nt i) {
    4      …
    5 }
    6 }

    介绍了把out当作参数修饰符的使用和在一个属性中的Out的使用。

    1.13 InterfaceType 属性

    当放在一个接口上, InterfaceType 属性指定了接口在COM被看作的样式。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Interface)]
    public class InterfaceTypeAttribute: System.Attribute
    {
         public InterfaceTypeAttribute(ComInterfaceType value) {…}

         public ComInterfaceType Value { get {…} }
    }
    }

    1.14 MarshalAs 属性

     MarshalAs 属性被用来描述一个域、方法或参数的集合形式。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Method | 
                   AttributeTargets.Parameter | 
                   AttributeTargets.Field)]
    public class MarshalAsAttribute: System.Attribute
    {
         public MarshalAsAttribute(UnmanagedType unmanagedType) {…}

         public UnmanagedType ArraySubType;

         public string MarshalCookie;

         public string MarshalType;

         public string MarshalTypeLibGuid;

         public string MarshalUnmanagedType;

         public VarEnum SafeArraySubType;

         public int SizeConst;

         public short SizeParamIndex;

         public int SizeParamMultiplier;
    }
    }

    1.15 NoIDispatch 属性

    NoIDispatch 属性的存在指示当要输出到COM时,类或接口要从IUnknown 中派生而不是IDispatch 。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
    public class NoIDispatchAttribute: System.Attribute
    {
         public NoIDispatchAttribute() {…}
    }
    }

    1.16 NonSerialized 属性

    NonSerialized 属性的存在于一个域和属性中,指出那个域或属性要被特殊化。

    namespace System 
    {
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
    public class NonSerializedAttribute: Attribute
    {
         public NonSerializedAttribute() {…}
    }
    }

    1.17 Predeclared 属性

    Predeclared 属性的存在表示一个预声明的对象从COM引入。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(Attribute(AttributeTargets.Class)]
    public class PredeclaredAttribute: System.Attribute
    {
         public PredeclaredAttribute() {…}
    }
    )

    1.18 PreserveSig 属性

    PreserveSig 属性被用来把一个方法标记为在COM中返回HRESULT 结果。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
    public class PreserveSigAttribute: System.Attribute
    {
         public PreserveSigAttribute(bool value) {…}

         public bool Value { get {…} }
    }
    }

    PreserveSig 属性被用来指出,通常在互用性调用中发生的HRESULT/retval 签名转换应该被禁止。

    1.19 Serializable 属性

    Serializable 属性存在于一个类中表示那个类要被特殊化。

    namespace System 
    {
    [AttributeUsage(AttributeTargets.Class 
                          | AttributeTargets.Delegate 
                          | AttributeTargets.Enum 
                          | AttributeTargets.Struct)]
    public class SerializableAttribute: System.Attribute
    {
         public SerializableAttribute() {…}
    }
    }

    1.20 StructLayout 属性

    StructLayout 属性被用来为一个结构指定域的布局。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
    public class StructLayoutAttribute: System.Attribute
    {
        public StructLayoutAttribute(LayoutKind value) {…}

        public CharSet CharSet;

        public bool CheckFastMarshal;

        public int Pack;

        public LayoutKind Value { get {…} }
    }
    }

    如果LayoutKind.Explicit 被指定,那么在结构中的每个域必须都有StructOffset 属性。如果LayoutKind.Explicit 没有被指定,那么StructOffset 属性的使用就被禁止了。

    1.21  TypeLibFunc 属性

     TypeLibFunc 属性被用来指定typelib 标记,用于与COM互用。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Method)]
    public class TypeLibFuncAttribute: System.Attribute
    {
         public TypeLibFuncAttribute(TypeLibFuncFlags value) {…}

         public TypeLibFuncFlags Value { get {…} }
    }
    }

    1.22 TypeLibType 属性

    TypeLibType 属性被用来指定typelib 标记,用于与COM互用。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
    public class TypeLibTypeAttribute: System.Attribute
    {
         public TypeLibTypeAttribute(TypeLibTypeFlags value) {…}

         public TypeLibTypeFlags Value { get {…} }
    }
    }

    1.23 TypeLibVar 属性

    TypeLibVar属性被用来指定typelib 标记,用于与COM互用。

    namespace System.Runtime.InteropServices
    {
    [AttributeUsage(AttributeTargets.Field)]
    public class TypeLibVarAttribute: System.Attribute
    {
         public TypeLibVarAttribute(TypeLibVarFlags value) {…}

         public TypeLibVarFlags Value { get {…} }
    }
    }

    1.24 支持的枚举

    namespace System.Runtime.InteropServices
    {
    public enum CallingConvention
    {
         Winapi = 1,
         Cdecl = 2,
         Stdcall = 3,
         Thiscall = 4,
         Fastcall = 5
    }

    public enum CharSet
    {
         None,
         Auto,
         Ansi,
         Unicode
    }

    public enum ComInterfaceType
    {
         InterfaceIsDual = 0,
         InterfaceIsIUnknown = 1,
         InterfaceIsIDispatch = 2,
    }

    public enum LayoutKind
    {
        Sequential,
        Union,
        Explicit,
    }

    public enum TypeLibFuncFlags
    {
         FRestricted = 1,
         FSource = 2,
         FBindable = 4,
         FRequestEdit = 8,
         FDisplayBind = 16,
         FDefaultBind = 32,
         FHidden = 64,
         FUsesGetLastError = 128,
         FDefaultCollelem = 256,
         FUiDefault = 512,
         FNonBrowsable = 1024,
         FReplaceable = 2048,
         FImmediateBind = 4096
    }

    public enum TypeLibTypeFlags
    {
         FAppObject = 1,
         FCanCreate = 2,
         FLicensed = 4,
         FPreDeclId = 8,
         FHidden = 16,
         FControl = 32,
         FDual = 64,
         FNonExtensible = 128,
         FOleAutomation = 256,
         FRestricted = 512,
         FAggregatable = 1024,
         FReplaceable = 2048,
         FDispatchable = 4096,
         FReverseBind = 8192
    }

    public enum TypeLibVarFlags
    {
         FReadOnly = 1,
         FSource = 2,
         FBindable = 4,
         FRequestEdit = 8,
         FDisplayBind = 16,
         FDefaultBind = 32,
         FHidden = 64,
         FRestricted = 128,
         FDefaultCollelem = 256,
         FUiDefault = 512,
         FNonBrowsable = 1024,
         FReplaceable = 2048,
         FImmediateBind = 4096
    }

    public enum UnmanagedType
    {
         Bool          = 0×2,
         I1            = 0×3,
         U1            = 0×4,
         I2            = 0×5,
         U2            = 0×6,
         I4            = 0×7,
         U4            = 0×8,
         I8            = 0×9,
         U8            = 0xa,
         R4            = 0xb,
         R8            = 0xc,
         BStr          = 0×13,
         LPStr         = 0×14,
         LPWStr     = 0×15,
         LPTStr     = 0×16,
         ByValTStr  = 0×17,
         Struct     = 0x1b,
         Interface  = 0x1c,
         SafeArray  = 0x1d,
         ByValArray = 0x1e,
         SysInt     = 0x1f,
         SysUInt       = 0×20,
         VBByRefStr

  • 相关阅读:
    菜鸟也为Git疯狂
    C#实现简单的栈和队列
    Entity Framework模型在领域驱动设计界定上下文中的应用
    SQL 关于使用CTE
    《高效程序员的45个习惯》读书笔记
    开源.NET下的XML数据库介绍及入门
    openkm开发环境搭建过程
    ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇
    《Clean Code》Learning
    网络抓包工具 Network Monitor使用方法 Fiddler使用方法
  • 原文地址:https://www.cnblogs.com/endv/p/6170077.html
Copyright © 2011-2022 走看看