托管 C++ 遗留 C++ 的包装器 图书馆
我们正在考虑使用托管 C++ 为一些旧版 C++ 库编写一个 .Net 可调用包装器。
一切看起来都很简单。 有什么需要我们注意的吗?
We're looking at writing a .Net-callable wrapper for some legacy C++ libraries using managed C++.
It all looks pretty easy. Is there anything we need to watch out for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我发现在 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:
它非常简单并且运行良好。 它比 PInvoke 容易得多。
您需要注意的一件大事是托管标头中没有任何非托管成员,包括私有成员、方法签名等。不过,拥有指向托管类型的指针的私有成员是可以的,只需对您的托管头使用前向声明即可。类。
另外,请注意对象的生命周期。 由于许多 .NET 程序员不习惯自行清理内存,因此很容易出现内存泄漏。 确保您创建的任何包装类(如果它们包含指针)都是一次性的,并确保在托管代码中处置它们。 托管 C++ 中 IDisposable 的语法也很奇怪,但它在文档中。
另外,请记住,每次跨越托管/非托管边界时,您都会遭受轻微的影响,因此请尝试相应地规划您的界面。 如果在循环中重复调用任何内容,最好将该循环移过边界,以便只跨越一次。 不过,除非您正在通话数百万个电话,否则不要太担心这一点。
这篇文章反其道而行之,但它有一些有用的观点。
使用我们的 ManWrap 库在本机 C++ 代码中充分利用 .NET
另请参阅
Visual Studio 2005 中的托管代码和
删除托管对象、包装库等
It is pretty straight-forward and works well. It is a lot easier than PInvoke.
The big thing you need to watch out for is not having any unmanaged members in your managed headers, including private members, method signatures, etc. It is okay to have private members that are pointers to managed types though, just use forward declarations for your classes.
Also, watch out for object lifetime. It is easy to introduce memory leaks since many .NET programmers are not used to cleaning up after themselves. Make sure any wrapper classes that you create are disposable if they contain pointers and make sure you dispose of them in your managed code. The syntax for IDisposable in managed C++ is also weird, but it is in the docs.
Also, remember that you incur a slight hit every time you cross the managed/unmanaged boundary, so try to plan your interface accordingly. If anything gets called repeatedly in loops, it is probably better to move that loop across the boundary so you only cross once. Don't worry too much about this though unless you are talking millions of calls.
This article goes the other way, but it has some useful points.
Use Our ManWrap Library to Get the Best of .NET in Native C++ Code
See also
Managed Code in Visual Studio 2005 and
Deleting Managed Objects, Wrapping a Library, and More
只是我们遇到的一些问题:
Just some issues which we encountered:
我将添加每个人都已经说过的内容,
pin_ptr wch = PtrToStringChars(string); (其中 string 是 System::String)
将成为您的朋友。
您不能直接将非托管类包含到托管类中,但您可以放置一个指向非托管类的指针,并在构造函数中新建它,并在析构函数中删除它。
我还没有遇到 Timo Geusch 提到的在一个 DLL 中混合 C++ 和 C++/CLI 代码的问题。 我的 DLL 广泛使用两者,没有出现任何问题。
C++/CLI 并不困难(如果您了解 C++ 和 .NET)并且效果很好。
I'll just add to what everyone has already said,
pin_ptr wch = PtrToStringChars(string); (where string is a System::String)
will become your friend.
You can't directly include a non-managed class into a managed class but you can put a pointer to the unmanaged class and new it in your constructor and delete it in your destructor.
I haven't had the problems Timo Geusch mentioned with mixing C++ and C++/CLI code in one DLL. My DLL uses both extensively without problems.
C++/CLI is not difficult (if you know C++ and .NET) and works great.
正如其他人所说:98% 的时间它都能正常工作、可调试且速度快。
到目前为止我遇到的问题还没有提到:
它甚至运行得非常好,以至于我开始编写 C++/CLI 代码来对 C++ 代码运行单元测试。 NUnit/Resharper 会很高兴地在 C++/CLI DLL 中找到并运行单元测试,它可以在任何级别直接调用您的本机代码,甚至测试您的模板容器类。
As said by others: 98% of the time it just works, its debuggable, and fast.
What I encountered beyond mentiond so far:
It even worked so well that I started on writing C++/CLI code to run unit tests on C++ code. NUnit/Resharper will happily find and run the unit test in a C++/CLI DLL, that can directly call into your native code at ANY LEVEL, even test your template container classes.