设为首页 加入收藏

TOP

VC 调用托管程序集(.Net Managed Assemblies) (一)
2014-11-23 19:22:45 】 浏览:440
Tags:调用 托管 程序 .Net Managed Assemblies

前言
.Net 类库功能非常全面分装了大量应用级别的API,所以有时会有在VC 中调用托管程序集(.Net Managed Assemblies) 的需求。本文通过示例对该步骤进行说明,并提供一些参考。

前提
本文假设已有一个现成可用的托管程序集,代码如下:

[csharp]
// 媒体类:用来载入一个媒体文件,并解析出信息
public class Media
{
// 内部处理
private void DoSomething()
{ ... }

// 载入文件
public void LoadMedia(string filePath)
{ ... }

// 获取媒体信息
public MediaInfo GetInfo()
{ ... }
}

// 媒体信息类
public class MediaInfo
{
// 内部标示
private Guid id;
// 文件名
public property string Name { get; set; }
}

// 媒体类:用来载入一个媒体文件,并解析出信息
public class Media
{
// 内部处理
private void DoSomething()
{ ... }

// 载入文件
public void LoadMedia(string filePath)
{ ... }

// 获取媒体信息
public MediaInfo GetInfo()
{ ... }
}

// 媒体信息类
public class MediaInfo
{
// 内部标示
private Guid id;
// 文件名
public property string Name { get; set; }
}托管程序集(.Net Managed Assemblies)
1 追加 ComVisible Attribute
要使一个托管程序集能作为 COM 被 VC 调用首先需要添加 ComVisible Attribute。如果你比较懒可以在项目的 AssemblyInfo.cs 文件中进行全局声明:

[csharp]
[assembly: ComVisible(true)]
[assembly: Guid("2aa76d89-5faf-473e-8285-b9199fedd365")]

[assembly: ComVisible(true)]
[assembly: Guid("2aa76d89-5faf-473e-8285-b9199fedd365")]当程序集的公有类相当多的时候这是个好办法,但是并不建议这样做,因为调用方(VC)通常并不需要访问程序集中的所有公有类,并且过多的暴露程序集也不太好。这里我们就勤劳点,在每个类上进行声明。

[csharp] view plaincopyprint [ComVisible(true)]
public class Media : IDisposable
{
// 略
}

[ComVisible(true)]
public class MediaInfo
{
// 略
}

[ComVisible(true)]
public class Media : IDisposable
{
// 略
}

[ComVisible(true)]
public class MediaInfo
{
// 略
}2 追加 ClassInterface Attribute
参照一下 MSDN 该 Attribute 需要传入一个 ClassInterfaceType 枚举来决定生成接口的方式:

AutoDual 指示自动为类生成双重类接口并向 COM 公开。为该类接口生成类型信息并在类型库中发布。由于 ClassInterfaceAttribute 中描述的版本控制方面的限制,极力建议不要使用 AutoDual。
AutoDispatch 指示该类只支持 COM 客户端的后期绑定。在请求时,该类的调度接口将自动向 COM 客户端公开。类型 类型库导出程序 (Tlbexp.exe) 生成的类型库不包含调度接口的类型信息,以防止客户端缓存接口的 DISPID。由于客户端只能后期绑定到调度接口,因此该接口不会出现 ClassInterfaceAttribute 中所述的版本控制问题。
这是 ClassInterfaceAttribute 的默认设置。
None 指示不为类生成类接口。如果未显式实现任何接口,则该类将只通过 IDispatch 接口提供后期绑定访问。这是 ClassInterfaceAttribute 的推荐设置。
既然官方推荐,那么我们就采用ClassInterfaceType.None,但是因为类接口不再自动生成,所以我们需要自己为 2 个类分别定义 2 个接口:

[csharp]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IMedia))]
public class Media : IDisposable, IMedia
{
// 略
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class MediaInfo : IMediaInfo
{
// 略
}

[ComVisible(true)]
public interface IMedia
{
void LoadMedia(string filePath);
MediaInfo GetInfo();
}

[ComVisible(true)]
public interface IMediaInfo
{
property string Name { get; set; }
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IMedia))]
public class Media : IDisposable, IMedia
{
// 略
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class MediaInfo : IMediaInfo
{
// 略
}

[ComVisible(true)]
public interface IMedia
{
void LoadMedia(string filePath);
MediaInfo GetInfo();
}

[ComVisible(true)]
public interface IMediaInfo
{
property string Name { get; set; }
}提示:

接口只需要定义公开给 Com 的接口,即如果VC 不需要调用 LoadMedia 方法,那么IMedia 接口中可以不包含该方法
接口本身也需要 ComVisible 声明
当某个类实现了多个接口的情况下,需要使用 ComDefaultInterface 明确指定 COM 接口是哪一个
3 生成支持 COM 调用托管程序集(.Net Managed Assemblies)
使用 VS 的话相当简单,在工程的属性页面里“Register for COM interop”打个钩就一切搞定,编译后去 bin 下面就能找到 .NET

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇vc++笔记----CRecordset类 下一篇vc++笔记-----MFC环境下的多任务..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目