这章中描述的属性被用在创建和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中指定一个成员。

  1. namespace System.Runtime.InteropServices
  2. {
  3. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
  4. public class DispIdAttribute: System.Attribute
  5. {
  6.      public DispIdAttribute(int value) {…}
  7.      public int Value { get {…} }
  8. }
  9. }

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 属性被用来为结构指定域的规划。

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

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

1.8 GlobalObject 属性

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

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

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

C#如何调用COM的更多相关文章

  1. 黑马毕向东Java基础知识总结

    Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记    侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...

  2. 《果壳中的C# C# 5.0 权威指南》 - 学习笔记

    <果壳中的C# C# 5.0 权威指南> ========== ========== ==========[作者] (美) Joseph Albahari (美) Ben Albahari ...

  3. JS调用Android、Ios原生控件

    在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...

  4. 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付

    前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...

  5. 操作系统篇-调用门与特权级(CPL、DPL和RPL)

    || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在前两篇文章(<操作系统篇-浅谈实模式与保护模式>和<操作系统篇-分段机制与GDT|LDT>)中,我们提到 ...

  6. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  7. django server之间通过remote user 相互调用

    首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...

  8. 调用AJAX做登陆和注册

    先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...

  9. nodejs进阶(2)—函数模块调用

    函数调用 1. 文件内普通函数调用 创建一个js文件命名为2_callFunction.js,其中定义一个函数fun1,向返回对象输出了一段字符串“你好,我是fun1”. //------------ ...

  10. 【初学python】使用python调用monkey测试

    目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...

随机推荐

  1. 走进AngularJs(七) 过滤器(filter)

    过滤器(filter)正如其名,作用就是接收一个输入,通过某个规则进行处理,然后返回处理后的结果.主要用在数据的格式化上,例如获取一个数组中的子集,对数组中的元素进行排序等.ng内置了一些过滤器,它们 ...

  2. 难道只有我一个人想吐槽npm这种包管理方式么

    实在忍不住吐槽 说实话有强迫症的我忍了很久了,实在是忍不住写篇文章来吐槽一下. 标题可能说的有点大了,我要吐槽的是:我可能只需要某一个小小的功能模块A,结果模块A依赖B-F这5个模块,然后B又依赖这1 ...

  3. 两个Fragment之间如何传递数据

    FragmentA启动FragmentB,做一些选择操作后,返回FragmentA,需要把FragmentB里面选择的数据传回来.有什么办法? Fragment之间不能直接通信,必须通过Activit ...

  4. 从Windows中卸载Apache

    在重装Apache或者妳不再需要它的时候,这时就需要将它卸载. 下面是步骤: 打开开始菜单(win8中ÿ+X)或者我的电脑(废话) 找到并打开Apache的安装目录(Program Files\Apa ...

  5. mysql: error while loading shared libraries: libmysqlclient.so.16

    [root@host_41 mysql]# mysqlmysql: error while loading shared libraries: libmysqlclient.so.16: cannot ...

  6. [翻译]AKKA笔记 - ACTOR MESSAGING - REQUEST AND RESPONSE -3

    上次我们看Actor消息机制,我们看到开火-忘记型消息发出(意思是我们只要发个消息给Actor但是不期望有响应). 技术上来讲, 我们发消息给Actors就是要它的副作用. 这就是这么设计的.除了不响 ...

  7. 翻译:AKKA笔记 - Actor消息 -1(二)

    消息 我们只是让QuoteRequest到ActorRef去但是我们根本没见过消息类! 它是这样的: (一个最佳实践是把你的消息类包装在一个完整的对象里以利于更好的组织) TeacherProtoco ...

  8. Node.js与Sails~项目结构与Mvc实现

    回到目录 Sails是一个Node.js的中间件架构,帮助我们很方便的构建WEB应用程序,网址:http://www.sailsjs.org/,它主要是在Express框架的基础上发展起来的,扩展了新 ...

  9. Java程序员的日常 —— 响应式导航Demo

    这两天想要做响应式的页面,于是本着重复造轮子的想法,模仿Bootstrap官网,精简了一个响应式导航的Demo. 效果 代码 <!DOCTYPE html> <html> &l ...

  10. document对象

    document 对象是操作网页内容的 找元素 1.根据id找 document.getElementById(); 2.根据class找 document.getElementsByClassNam ...