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
 
 
 
 
 
 
 

 
       
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号