用C ++ / CLI包装非托管C ++类库
注意:这篇文章代表了我询问的问题#2。 在两个问题中重复介绍块(所有文本直到达到数字),因为它是可能需要回答问题的背景信息。
问题介绍
我有一个非托管的C ++库,其中包含通用的类和函数,并在多个“更高级别”库中共享。 我现在需要提供对C#/ .Net应用程序的公共库。 为此,我将不得不使用C ++ / CLI包装类来包装公共库。
公共库中包含的类可以是包含嵌套类定义和其他类对象集合的成员变量的复杂类。 集合变量是用于管理集合的自定义列表类的typedefs实例。 公共库还包括代表使用FLEX / BISON创建的自定义脚本文件语法的解析结构的类。 通用库和“更高级别”库都是以允许跨平台(Linux和GCC)编译和使用的方式编写的。 我所做的任何更改都必须考虑到这一点。
C ++ / CLI包装类首先只需要读取功能。 但随着项目的进展,我最终还需要能够创建和修改对象。
我知道C ++ / CLI,并为其他非托管C / C ++项目创建了多个包装器,并为相同的公共库提供了抽象的功能。 所以我已经有了基础知识(以及一些高级知识)。
我有两个与执行此任务有关的问题,既然他们可以产生他们自己的讨论和解决方案,我将我的问题分解成单独的帖子。 我将在每篇文章中包含指向其他问题的链接。
实际问题
用C ++ / CLI包装非托管C ++类库 - 问题1 - 项目/代码组织
我如何有效地包装/处理非托管类中的集合变量?
集合对象是为了处理对象指针集合的管理而编写的自定义模板列表类( CObjectList<T>
)的类型定义。 集合类提供了所有基本的集合功能以及指针管理和清理解除对象上的清理/释放。 所以对于CWidget
,将会有一个typedef CObjectList<CWidget> CWidgetList;
在代码中。
代码和集合类模板参数中使用的大多数类都是类本身。 但在某些情况下,该集合是基类。 这发生在自定义脚本FLEX / BISON解析器的解析结构中。 例如,有一个CCommand
类可以继承所有其他可用命令。 所以会有CSetCommand
, CPrintCommand
, CIfCommand
等。
我想要做到这一点,我将不得不创建我的集合包装类,它为非托管和C ++ / CLI类维护单独的列表。 内部集合对象将管理非托管对象,并且必须有一个托管集合/列表对象来存储该项目的包装类。
有没有人有任何关于如何做到这一点的例子/建议? 或者如何编写一个可以将非托管和C ++ / CLI类类型作为参数的泛型类?
这是一个很难回答的问题,但我会建议你有一个从托管集合转换到非托管集合的编组/转换层。 保持您的库完全保持原样,然后转换参数并返回。
这是我会做的,如果
由于这些原因
这将是我的默认方法,除非我真的需要访问数据结构中lib的功能(它不仅仅是有组织的数据 - 而是数据和行为)
娄有一个很好的建议,我同意他的方法是什么时候这种方法是好的。
如果集合非常大,或者经常来回传递,那么最好是实现.NET可枚举接口,但不使用.NET集合。 基本上,你将拥有一个拥有本地STL集合的集合包装器和一个拥有本地STL迭代器的迭代器包装器。 集合包装器将实现IEnumerable
接口, GetEnumerator
将创建迭代器包装器的实例,迭代器包装器将实现IEnumerator
接口。
你会想让自己成为一个帮助器托管类(可能是一个值类),它将指针包装到本地集合中,并执行引用计数,如boost::shared_ptr
。 使用堆栈语义符号来确保引用计数在托管集合包装器或迭代器包装器处理完成时自动完成。