删除托管对象 如何果包装一个库?及其它......

2016-01-29 12:25 5 1 收藏

删除托管对象 如何果包装一个库?及其它......,删除托管对象,如何果包装一个库?及其它......

【 tulaoshi.com - C语言心得技巧 】

C++ Q&A 专栏...
删除托管对象,如何包装一个库?及其它......

原著:Paul DiLascia
翻译:Northtibet

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)

原代码下载:CQA0412.exe (235KB)
原文出处:MSDN Magazine December 2004 (C++ Q&A) 删除托管对象

如何包装一个库?

如何将托管 String 转换回本地的 TCHAR*? 如何改变标签控件的背景颜色?

在托管 C++ 中,请告诉我使用 delete 操作符销毁托管对象是否安全?Bernie Sanders 是的,在托管 C++ 中,你可以删除( delete )托管对象,只要你理解删除只不过是调用对象的析构函数,但析构函数必须显示定义。调用 delete 不会释放对象的存储区。只有垃圾收集器才行。Figure 1 展示了一个简单的程序,该程序定义了一个带析构函数的托管类,当它运行的时候会显示一条信息。TESTDTOR 分配两个 ManagedClass 实例。它显式删除第一个实例,但第二个则不然。如果运行 TESTDTOR,你会得到象下面这样的结果:

Begin mainManagedClass(04A712D4)::ctorManagedClass(04A712D4)::dtorManagedClass(04A712E0)::ctorEnd mainManagedClass(04A712E0)::dtor

  它说明了当 delete 语句执行时,第一个对象的析构函数立即执行;而第二个对象(at 04A712E0)则没有被销毁,直到控制离开 main 并且系统终止代码调用垃圾收集器释放逗留对象。


Figure 2 Testdtor 的精彩输出

  不管什么时候,如果你不能确定 .NET 环境中发生了什么,你总是可以编写一些代码,编译它并检查微软中间语言(MSIL)产生的东西。正如 Figure 2 所展示的,定义析构函数导致编译器产生两个方法:一个是 Finalize 方法,它包含你的实现(这里是调用 printf),一个是 __dtor 方法,它调用 System.GC::SuppressFinalize,然后再调用  Finalize。当你删除对象时,编译器产生一个对此 __dtor 方法的掉用。如果你用 /FAs 编译 TESTDTOR 来产生有源码的程序集清单,你将看到 delete 语句以如下的方式编译:

; delete pmc;ldloc.0 ; _pmc$call ??1ManagedClass@@$$FQ$AAM@XZ

奇怪神秘的符号是被修饰过的析构函数(__dtor)。
  老练的 C++ 程序员可能会弄不明白,如果调用 delete 都无法释放对象,那调用它有干什么?好问题。调用 delete 的唯一理由是收回任何你的类所使用的非托管资源。例如,如果你的对象打开数个文件或创建了数据库连接,你可以写一个关闭其资源的析构函数,然后在用完该对象时使用 delete 释放它。在托管类中释放资源的一个更好的方法是通过实现 Dispose 模式,IDisposable——如果你在写托管 C++ 代码——由 auto_dispose 来调用它。(更多的信息参见 Tomas Restrepo 在 MSDN 杂志 2002 二月刊上的文章:“Tips and Tricks to Bolster Your Managed C++ Code in Visual Studio .NET”)。
  如果你实现 dispose 模式,其他的 .NET 使用者也可以使用它。如果你自己在析构函数中进行清理,其它语言便没有办法显式调用你的清理代码。因为在 C# 和 Visual Basic 中没有 delete 操作符。
  所以结果是你能调用 delete 来触发你的析构函数,但是将清理代码放在析构函数中可能不是一个好主意。最好是实现 IDisposable,这样所有人都能使用。注意,在 Visual C++ 2005 中,这个行为有所改变。更多信息参见 Andy Rich 对这个问题的讨论:“Deterministic Finalization IV - Benefits, part II”,以及当前的 C++/CLI 语言规范标准:“C++/CLI Language Specification Standard”

我有一个返回链表的非托管函数,其中有 char* 字符串:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com)
struct blah {   int a, b;   char *a, *b;   struct blah *next;};struct blah *getmystruct();

  因为 getmystruct() 分配内存,当用完之后,我需要调用 freemystruct(struct blah *b)。我尝试做一个包装器,用它来将之转换成托管类型的集合,但我不知道当需要释放所有这些指针的时候,该如何来处理。你能否赐教

来源:http://www.tulaoshi.com/n/20160129/1486005.html

延伸阅读
MSXML中提供了Microsoft.XMLHTTP对象,能够完成从数据包到Request对象的转换以及发送任务。 创建XMLHTTP对象的语句如下: Set objXML = CreateObject(Msxml2.XMLHTTP) 或 Set objXML = CreateObject(“Microsoft.XMLHTTP”) ' Or, for version 3.0 of XMLHTTP, use: ' Set xml = Server.CreateObject(MSXML2.ServerXMLHTTP) 对象创...
标签: flash教程
在课件制作过程中,我们常常要用到共享库,Flash为我们提供了3个公用库:按钮、声音和学习交互,这是系统自带的公用库。因此在公用“库”面板中不能添加新元件和文件夹,不能对其元件进行重命名、删除等操作。但如果对共享库中的元件不太满意,同时又想增加新的内容,怎么办呢?让我来教您一招。   图1 “库”面板中...
使用API函数SHGetSpecialFolder。shlobj.h里有SHGetSpecialFolder的原型声明。这个函数可以帮我们找到windows的Desktop目录、启动目录、我的文档目录等。 SHGetSpecialFolder需要三个参数。 第一个参数是HWND,它指定了"所有者窗口":在调用这个函数时可能出现的对话框或消息框。第二个参数是一个整数id,决定哪个目录是待查找目录,...
Function CreateNormalDB(strPathName As String) As Boolean On Error GoTo Exit_ERR Dim wrkDefault As Workspace Dim NewDB As Database CreateNormalDB = False Set wrkDefault = DBEngine.Workspaces(0) If Dir(strPathName) < "" Then Kill strPathName Set NewDB = wrkDefault.CreateDatabase(strPathName, dbLangGeneral) NewDB.Cl...
炎热夏季如何给宝宝洗一个安全清凉澡?——洗澡看变化 正宝从出生到现在,每天的洗澡从未间断过,不管是睡着还是醒着,高兴还是哭闹,健康还是生病,正妈都照样给正宝每日一澡。而改变的只是从原来的冬天每天上午洗澡改为了后来晚上睡前洗澡。正宝在一天天长大,而洗澡的方式也逐渐在转变。由最初的怀抱洗澡到自己坐在盆里洗澡,让正妈感...

经验教程

66

收藏

29
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部