快速业务通道

如何删除托管对象及包装一个库

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
ListWrap,它示范了具体做法。第一个模块,ListLib.cpp,实现一个本地 C++ 库(DLL),其中有两个函数,AllocateList 和 FreeList。分别用来分配和释放本地 C++ 结构链表。它们模仿你程序中的 getmystruct 和 freemystruct 函数。第二个模块是一个托管 C++ 文件,ListWrap.cpp,它实现托管类 ManagedNode,该类包装本地 C++ 实现(参见 Figure 3)。第三个模块是 C# 测试程序,它调用包装器来展示它如何工作。详情请下载源代码。

ListLib.cpp 实现两个本地函数,AllocateList 和 FreeList,这两个函数用来分配和释放 NativeNode 结构链表:

// from ListLib.h
struct NativeNode {
  int a, b;
  TCHAR *str;
  struct NativeNode *next;
};

ListWrap.cpp 中的包装器类 ManagedNode 模仿用 NativeNode 的定义,只是有两个小差别:本地 char* 被用托管的 String 代替,此外它没有 next 指针,因为我将用 ArrayList 实现链表结构。代码如下:

// managed equivalent of NativeNode
public __gc class ManagedNode {
public:
int a, b;
String* str;
};

有了 ManagedNode 的定义,下一步是编写代码将 NativeNodes 转换到 ManagedNodes。但在开始之前,先停下来考虑一下转换函数应该是什么样子,他应该有什么样的参数,返回什么值。一种方法是编写一个函数,参数是本地 NativeNodes 链表并返回托管的 ManagedNodes 链表,在这个过程中可能销毁本地链表。.NET 客户端应用程序将直接调用 ListLib DLL (或你的 getmystruct )以获取本地链表,将它作为 IntPtr 类型。然后,将这个 IntPtr 传递给转换函数,象下面这样:

// call DLL directly through interop
IntPtr nativeList = AllocateList(7);
// call wrapper to convert
ArrayList amanagedList = ListWrap.Convert(nativeList);

大多数情况下,客户端将负责调用该 DLL 来释放本地链表,或者 Convert 函数自动完成。

一种不同的方法是通过在某个包装器中包装分配链表的本地函数 AllocateList 来完全隐藏这个 DLL,转换并在作为 ArrayList 返回托管链表之前释放原来的本地链表。哪种方法更好的呢?第一种策略的优点是你只需要编写单一的转换函数,它便可以在任何有本地链表的地方使用。第二个方法需要对每个创建链表的函数进行包装。如果有多个创建链表的函数,则工作量稍大一些。但是其优点是它向 .NET 客户端完全隐藏了所有的本地处理逻辑和细节。客户端不再需要去处理 IntPtrs 或甚至是导入此 DLL,因为 ListWrap 隐藏了一切。这是我将要采用的方法,同时也是我鼓励你在自己的程序中使用的方法。尽管对库进行完全的包装需要更多的努力,但是结果却更加可靠和彻底的封装。

有了 ManagedNode,剩下的事情便是包装 AllocateList。这个过程非常简单直白。首先,调用 AllocateList 分配本地链表,然后创建一个空的 ArrayList,接着将所有 NativeNodes 拷贝到 ManagedNodes 并将它们添加到托管链表中,最有离开时删除它们。Figure 3 展示了所有的细节。托管 C++ 的优美之处在于即便是在处理混合对象时,所有的代码看起来都很简朴优雅。将本地 char* 拷贝到托管 String 用一个赋值即可,就像下面这行代码:

mn->str = nn->str; // String = char*: it just works!

不需要调用转换函数;编译器知道该怎么做。离开 CreateList 时删除本地节点。这样做比在末尾删除它们存储更有效。

通过将整个链表转换到托管对象(而不是用 interop 和 StructLayout 将它导出),使托管客户端不用离开托管世界,此谓入乡随俗也!毕竟,某些程序员选择 .NET 的一个主要理由是其自动的垃圾收集。如果你用 interop 直接导出链表,那么你也必须导出 FreeList,从而必须让使用基于 .NET 语言

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号