常见的托管C ++陷阱

时间:2011-06-10 16:26:01

标签: c++-cli managed-c++

在几乎完全使用非托管C ++之后第一次编写managed-C ++时,需要注意哪些最常见的问题?

4 个答案:

答案 0 :(得分:2)

使用内置的IJW(It Just Works)技术将托管委托转换为指向函数的指针时,指向函数的指针不会保存对委托所来自的对象的引用。如果您不安排以其他方式保存引用,则可能会收集托管对象,然后在调用该函数时,您将获得NullReferenceException。

如果要创建一个需要回调的C库,并且想要将其包装在Managed类中,则会遇到很多问题。托管类的客户端将提供一个委托,您将其转换为回调。您还必须保留对委托或目标对象的引用。

在Managed C ++和C ++ / CLI中也是如此。

答案 1 :(得分:1)

如果您的意思是C ++ / CLI ......

  • 在通过引用传递参数时忘记使用pin_ptr。与此相关,理解跟踪句柄和指针之间的区别至关重要。请参阅Expert C++/CLI的第一章。
  • C ++ / CLI没有C#的yield构造,我们在使用TestCaseSource属性生成测试用例数据时使用Nunit编写单元测试时使用了很多。这与下一个有关。
  • 实现System :: IEnumerable非常麻烦。但是一旦你做了一次,你有一个参考,所以它并没有那么糟糕。
  • 理解析构函数和终结符之间的区别非常重要。有关此问题的讨论,请参阅Expert C++/CLI
  • 的第4章

答案 2 :(得分:1)

这是另一个问题:在对象上执行方法构成对象的引用。这意味着在执行成员方法期间,对象可能会在方法仍在执行时清除对象,但在最后一次引用this对象之后,终结器可能会触发。

如果您的对象具有通过finalization清理的任何非托管状态或包含具有此类非托管状态的任何其他对象,您正在对该非托管状态进行计算,请确保在{{1}上调用GC::KeepAlive在那些非托管计算之后。我现在倾向于将this附加到具有非托管计算的所有对象方法。

答案 3 :(得分:0)

一个问题(刚刚得到我):假设“析构函数只能执行一次”。由于析构函数是通过Dispose调用的,并且Dispose可能被多次调用,因此这个假设(适用于C ++)不适用于C ++ / CLI。