C#如何调用COM
这章中描述的属性被用在创建和COM程序交互的程序中。
1.1 COMImport 属性
当被放在一个类上, COMImport 属性就把这个类标记为一个外部实现的COM 类。这样的一个类声明使得可以用一个C# 名称调用一个COM 类。
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Class)]
public class COMImportAttribute: System.Attribute
{
public COMImportAttribute() {…}
}
}
用COMImport 属性修饰的类要受下面的限制:
- 它必须也被Guid 属性修饰,它为被引入的COM类指定了CLSID 。如果一个类声明包含COMImport 属性,但是没有包含Guid 属性,就会发生一个编译时错误。
- 它不能有任何成员。(一个没有参数的公共构造函数会被自动提供。)
- 他必须从object类派生。
示例
using System.Runtime.InteropServices;
[COMImport, Guid("00020810-0000-0000-C000-000000000046")]
class Worksheet {}
class Test
{
static void Main() {
Worksheet w = new Worksheet(); // Creates an Excel worksheet
}
}
声明了一个类Worksheet ,这个类作为一个类从有CLSID “00020810-0000-0000-C000-000000000046″的COM引入。一个Worksheet 实例的实例化造成了一个相应的COM实例化。
1.2 COMRegisterFunction 属性
一个方法中的COMRegisterFunction 属性的实现,指示出这个方法应该在COM注册过程中被调用。
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Method)]
public class COMRegisterFunctionAttribute: System.Attribute
{
public ComRegisterFunctionAttribute() {…}
}
}
1.3 COMSourceInterfaces 属性
COMSourceInterfaces 属性用来列出引入的联合类中的源接口。
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Class)]
public class ComSourceInterfacesAttribute: System.Attribute
{
public ComSourceInterfacesAttribute(string value) {…}
public string Value { get {…} }
}
}
1.4 COMVisible 属性
COMVisible 属性用来指定一个类或接口在COM中是否可见。
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class COMVisibleAttribute: System.Attribute
{
public COMVisibleAttribute(bool value) {…}
public bool Value { get {…} }
}
}
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的位置。
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Method)]
public class DllImportAttribute: System.Attribute
{
public DllImportAttribute(string dllName) {…}
public CallingConvention CallingConvention;
public CharSet CharSet;
public string EntryPoint;
public bool ExactSpelling;
public bool SetLastError;
public bool TransformSig;
public string Value { get {…} }
}
}
特别地, 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的互用性中。
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Class
| AttributeTargets.Interface
| AttributeTargets.Enum
| AttributeTargets.Delegate
| AttributeTargets.Struct)]
public class GuidAttribute: System.Attribute
{
public GuidAttribute(string value) {…}
public string Value { get {…} }
}
}
位置字符串参数的形式在编译时被验证。指定一个在不是句法上有效的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 属性被用来为参数提供自定义集合信息。这些集合属性的所有组合都是允许的。
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Parameter)]
public class InAttribute: System.Attribute
{
public InAttribute() {…}
}
[AttributeUsage(AttributeTargets.Parameter)]
public class OutAttribute: System.Attribute
{
public OutAttribute() {…}
}
}
如果一个参数没有被任何集合属性修饰,那么它就是基于它的参数修饰符,就像下面一样。如果参数没有修饰符,那么集合是 [In]。 如果参数有ref 修饰符,那么集合是 [In, Out]。 如果参数有out修饰符,那么集合是 [Out]。
注意out是一个关键字,而Out是一个属性。示例
class Class1
{
void M([Out] out i, nt i) {
…
}
}
介绍了把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的更多相关文章
- 黑马毕向东Java基础知识总结
Java基础知识总结(超级经典) 转自:百度文库 黑马毕向东JAVA基础总结笔记 侵删! 写代码: 1,明确需求.我要做什么? 2,分析思路.我要怎么做?1,2,3. 3,确定步骤.每一个思路部 ...
- 《果壳中的C# C# 5.0 权威指南》 - 学习笔记
<果壳中的C# C# 5.0 权威指南> ========== ========== ==========[作者] (美) Joseph Albahari (美) Ben Albahari ...
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
- 【原创分享·支付宝支付】HBuilder打包APP调用支付宝客户端支付
前言 最近有点空余时间,所以,就研究了一下APP支付.前面很早就搞完APP的微信支付了,但是由于时间上和应用上的情况,支付宝一直没空去研究.然后等我空了的时候,发现支付宝居然升级了支付逻辑,虽然目前还 ...
- 操作系统篇-调用门与特权级(CPL、DPL和RPL)
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在前两篇文章(<操作系统篇-浅谈实模式与保护模式>和<操作系统篇-分段机制与GDT|LDT>)中,我们提到 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- django server之间通过remote user 相互调用
首先,场景是这样的:存在两个django web应用,并且两个应用存在一定的联系.某些情况下彼此需要获取对方的数据. 但是我们的应用肯经都会有对应的鉴权机制.不会让人家随随便便就访问的对吧.好比上车要 ...
- 调用AJAX做登陆和注册
先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...
- nodejs进阶(2)—函数模块调用
函数调用 1. 文件内普通函数调用 创建一个js文件命名为2_callFunction.js,其中定义一个函数fun1,向返回对象输出了一段字符串“你好,我是fun1”. //------------ ...
- 【初学python】使用python调用monkey测试
目前公司主要开发安卓平台的APP,平时测试经常需要使用monkey测试,所以尝试了下用python调用monkey,代码如下: import os apk = {'j': 'com.***.test1 ...
随机推荐
- 旺信UWP倒计时
Bug数量: 2016/3/8: 34 2016/3/9: 40(一堆新Bug到来) 2016/3/10: 21(邀请用户内测,一大波虫子即将到来) 2016/3/11: 10(预期的一大波Bug还没 ...
- Java中类继承、接口实现的一些细节(长期更新)
前言 在Java中,子类继承父类,类实现接口是属于常识性的内容了,作为一个Java程序员应该也比较熟悉.不过子类继承父类,类实现接口中还是有一些小细节值得注意一下,本文就从个人工作.学习中入手,总结一 ...
- http 各个状态码及对应的java 编程
http的状态? 200 301 302 400 404 500 501 等等 如何编码? 其实这个是web服务器的范畴.服务器处理各个请求的时候,如果正常, 自然就是200 http://www.c ...
- java 锁!
问题:如何实现死锁. 关键: 1 两个线程ta.tb 2 两个对象a.b 3 ta拥有a的锁,同时在这个锁定的过程中,需要b的锁:tb拥有b的锁,同时在这个锁定的过程中,需要a的锁: 关键的实现难点是 ...
- 纯js 判断手势滑动方向
$('body').on('touchstart', '#gallerySlider img', function(e) { var touch = e.originalEvent, startX = ...
- iOS Crash常规跟踪方法及Bugly集成运用
当app出现崩溃, 研发阶段一般可以通过以下方式来跟踪crash信息 #1.模拟器运行, 查看xcode错误日志 #2.真机调试, 查看xcode错误日志 #3.真机运行, 查看device系统日志 ...
- Java程序员的日常 —— 注册工厂的妙用
注册工厂是一种很常用的框架书写方法,它适合于快速创建相同类型的对象. 举个栗子 比如一个家具工厂,有沙发.椅子.茶几等等,正常的编程模式是这样的: //创建 class 沙发{} class 椅子{} ...
- 动手搭个wordpress
看到很多人都是自己搭建博客服务器,然后一切都在自己的掌控之下,这样就不存在什么迁移,数据安全之类的问题,当然需要自己搞个空间了,不过现在都便宜的不行,$15/year,也是醉了.我不怎么写博客,但是个 ...
- java常用命令行指令
javac 将java源文件编译成class字节码文件 javac HelloWorld.java java (1)运行class文件 java HelloWorld 注意java命令后面不要加.cl ...
- switch判断注意点
if判断,如果判断的两个值类型不同,会继续隐性转换,==,当然如果使用===就不会. 1 if(2=="2"){ 2 console.log("true"); ...