从本机代码中使用 .NET 集合
一个简短的示例,说明如何从本机 C++/ATL 访问托管的字符串 ArrayList
引言
随着项目迁移到 .NET Framework,通常需要将新开发的基于 .NET 的功能集成到现有但尚未迁移的旧版 COM 应用程序中。 理想情况下,在 .NET Framework 上开发的代码应利用该框架提供的丰富的类库。 这会给希望使用托管代码的 COM 客户端带来一些问题,因为 COM 和 .NET 具有不同的对象模型、内存模型和运行时要求。
幸运的是,许多 .NET Framework 类通过 *mscorlib.tlb* 向 COM 客户端公开。 快速查看 OleView 中的 *mscorlib.tlb* 可以发现基本框架中有多少是 COM 可见的

还有许多类对 COM 对象可见。 事实上,API 文档中标记为 ComVisible(true)
的每个类都可以从 COM 客户端轻松访问。
Using the Code
此示例演示如何从本机 C++ 使用 System.Collections.ArrayList
。 C++ 客户端使用 ATL。
托管类方法 Library.GetBooks()
返回一个 ArrayList
。 单个 string
已在 Library()
构造函数中添加到此列表。 以下代码段打印列表中项目数的 count
(在此示例中,只有一个)
ILibraryPtr ptrLibrary(__uuidof(Library));
IUnknown *ptrUnkBooks = NULL;
// ManagedCSharpDemoLibrary::_ArrayList is a stub struct
// created by InteropServices. Since everything in COM
// derives from IUnknown, it's safe to cast from an IUnknown *
ptrLibrary->GetBooks((ManagedCSharpDemoLibrary::_ArrayList **)&ptrUnkBooks);
// ICollection is defined in mscorlib.tlb. It corresponds
// to System.Collections.ICollection
ICollection *ptrCol = NULL;
ptrUnkBooks->QueryInterface(__uuidof(ICollection), (void **)&ptrCol);
long count = -1;
ptrCol->get_Count(&count);
cout << "Number of books: " << count << endl;
System.Collections.ICollection.Count
属性包含 ArrayList
中的项目数。 ICollection
只是 ArrayList
实现的众多接口之一。 这些接口中的每一个都被声明为双接口,因此它可以被早期绑定客户端(如这个 C++ 客户端)以及后期绑定客户端(例如 VBscript)访问。
要访问 ArrayList
中的各个项目,需要 IList
接口。 托管世界中的 IList.Item
属性提供对列表元素的基于零的索引访问。 可以按如下方式访问此属性
IList *ptrList = NULL;
ptrCol->QueryInterface(__uuidof(IList), (void **)&ptrList);
// ArrayLists store objects. These are marshalled as
// VARIANTs. Since this list is storing strings, the
// VARIANTs are of type BSTR;
VARIANT vObj;
_variant_t vtObj; // provides a convenient way to convert to _bstr_t
for (int i=0; i < count; i++)
{
ptrList->get_Item(i, &vObj);
vtObj.Attach(vObj);
wcout << "Found book: " << ((_bstr_t)vtObj) << endl;
}
ptrCol->Release();
此示例打印列表中的每个元素。 它可以很容易地适应不是 string
的列表。 VT_* VARIANT
宏可用于确定列表中 VARIANT
的类型。
关注点
COM C++ 编译器扩展可以大大简化 C++ 中的 COM 编程。 属性编程还提供了另一种从 C++ 轻松创建和使用 COM 类型的方法,但是仍然存在很多使用早于属性编程的 VC++ 版本的遗留项目。
历史
- 2008 年 5 月 29 日:提交的第一个版本