托管C ++包装为传统的C ++库 [英] Managed C++ wrappers for legacy C++ libraries

查看:144
本文介绍了托管C ++包装为传统的C ++库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在考虑使用托管C ++编写.Net的调用包装对于一些传统的C ++库。

We're looking at writing a .Net-callable wrapper for some legacy C++ libraries using managed C++.

这一切看起来pretty的方便。有什么需要我们注意?

It all looks pretty easy. Is there anything we need to watch out for?

推荐答案

我发现它通常很容易将保鲜膜中的C ++ / CLI一些现有的C ++库和遇到的比较少的缺陷。那些我还记得是:

I found it generally quite easy to wrap some existing C++ libraries in C++/CLI and encountered comparatively few pitfalls. The ones I can remember were:

  • 在混合非托管C ++ $ C $在相同的可执行文件/ DLL的C和C ++ / CLI code是一个非常糟糕的主意。我碰到的问题与竞争的内存管理器在关机时间的方式(基本上是.NET运行时和普通C ++运行时,其中踩着对方的脚趾,当它来清理内存关机,导致不确定性的行为,以其中一个释放的)。取而代之的是静态的传统的C ++库链接到C ++ / CLI库,我创建了一个包含了传统的C ++和链接,对在C ++ / CLI DLL,它解决了这个问题一劳永逸。
  • 系统DLL
  • 如果您的code是用枚举,不得不将那些在适当的C ++ / CLI枚举类,否则其他.NET语言将无法看到和使用它们。
  • 在C ++ / CLI对象只能容纳指向非托管C ++对象。不幸的是在某些情况下,这意味着你必须创建瘦包装层来处理特定对象。我的最爱是,我不得不要么包装的boost :: shared_ptrs这种方式(从而添加另一层间接的),或者把它们放进shared_ptrs与空删除器穿越.NET /本地边界之后。无论是当你必须处理使用这种构造有很多的API是非常好的。 RAII没有越过这个边界,因此被警告,你将有一些时间来投入到调整到了.NET的方式相匹配。
  • 在C ++ / CLI没有做多继承,因此,如果您的旧库的利用,你可能需要使用这个接口模型等。
  • 在内部编组code似乎能够处理最POD转换,但你必须查找/借code可以转换的std ::字符串等,这code是各地,几在谷歌分钟应该把它(对不起,没有方便的在这里的时刻的任何链接)。
  • Mixing unmanaged C++ code and C++/CLI code in the same executable/DLL is a really bad idea. I've run into problems with competing memory managers at shutdown time that way (basically the .NET runtime and the regular C++ runtime where stepping on each other's toes when it came to cleaning up memory on shutdown, resulting in non-deterministic behaviour as to which one freed what). Instead of linking the static legacy C++ library into the C++/CLI library, I created a DLL containing the legacy C++ and linked that against the C++/CLI DLL, which solved the problem once and for all.
  • If your code is using enums, you have to wrap those in the appropriate C++/CLI enum classes, otherwise other .NET languages won't be able to see and use them.
  • C++/CLI objects can only hold pointers to unmanaged C++ objects. Unfortunately in certain cases, this means you will have to create thin wrapper layers to handle certain objects. My "favourite" was that I had to either wrap boost::shared_ptrs that way (and thus add another layer of indirection) or put them into shared_ptrs with null deleters after crossing the .NET/native boundary. Neither is very nice when you have to deal with APIs that use this sort of construct a lot. RAII doesn't cross this boundary, so be warned, you will have to invest some time into tweaking it to match the .NET way.
  • C++/CLI doesn't do multiple inheritance, so if your legacy library is making use of that you might have to model this using interfaces etc.
  • The internal marshalling code seems to be able to handle most POD conversions, but you'll have find/borrow code that converts std::strings etc. This code is around, a few minutes on Google should bring it up (sorry, don't have any links handy here at the moment).

这篇关于托管C ++包装为传统的C ++库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆