使用 Visual Studio 在 Windows 上混合 C# 代码和 umanaged C++ 代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/76629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:12:45  来源:igfitidea点击:

Mixing C# Code and umanaged C++ code on Windows with Visual Studio

c#windowsvisual-c++unmanaged

提问by David Segonds

I would like to call my unmanaged C++ libraries from my C# code. What are the potential pitfalls and precautions that need to be taken? Thank you for your time.

我想从我的 C# 代码中调用我的非托管 C++ 库。有哪些潜在的陷阱和需要采取的预防措施?感谢您的时间。

采纳答案by Michael Burr

This question is too broad. The only reasonable answer is P/Invoke, but that's kind of like saying that if you want to program for Windows you need to know the Win32 API.

这个问题太宽泛了。唯一合理的答案是 P/Invoke,但这有点像说如果你想为 Windows 编程,你需要知道 Win32 API。

Pretty much entire books have been written about P/Invoke (http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X), and of course entire websites have been made: http://www.pinvoke.net/.

几乎整本关于 P/Invoke 的书都写过(http://www.amazon.com/NET-COM-Complete-Interoperability-Guide/dp/067232170X),当然还有完整的网站:http:// www.pinvoke.net/

回答by Jesse C. Slicer

There are a couple routes you can go with this - one, you can update your unmanaged C++ libraries to have a managed C++ extensions wrapper around them and have C# utilize those classes directly. This is a bit time-consuming, but it provides a nice bridge to legacy unmanaged code. But be aware that managed C++ extensions are sometimes a bit hard to navigate themselves as the syntax is similar to unmanaged C++, but close enough that a very trained eye will be able to see the differences.

您可以使用几种方法 - 一个,您可以更新您的非托管 C++ 库以在它们周围使用托管 C++ 扩展包装器,并让 C# 直接利用这些类。这有点耗时,但它为遗留的非托管代码提供了一个很好的桥梁。但请注意,托管 C++ 扩展有时有点难以自行导航,因为其语法与非托管 C++ 相似,但足够接近,训练有素的眼睛将能够看到差异。

The other route to go is have your umnanaged C++ implement COM classes and have C# utilize it via an autogenerated interop assembly. This way is easier if you know your way around COM well enough.

另一种方法是让您的未管理的 C++ 实现 COM 类,并让 C# 通过自动生成的互操作程序集使用它。如果您对 COM 足够了解,这种方法会更容易。

Hope this helps.

希望这可以帮助。

回答by DougN

You're describing P/Invoke. That means your C++ library will need to expose itself via a DLL interface, and the interface will need to be simple enough to describe to P/Invoke via the call attributes. When the managed code calls into the unmanaged world, the parameters have to be marshalled, so it seems there could be a slight performance hit, but you'd have to do some testing to see if the marshalling is significant or not.

您正在描述 P/Invoke。这意味着您的 C++ 库将需要通过 DLL 接口公开自身,并且该接口需要足够简单以通过调用属性向 P/Invoke 进行描述。当托管代码调用非托管世界时,必须对参数进行编组,因此性能似乎可能会受到轻微影响,但您必须进行一些测试以查看编组是否重要。

回答by DougN

The easiest way to start is to make sure that all the C++ functionality is exposed as 'C' style functions. Make sure to declare the function as _stdcall.

最简单的开始方法是确保所有 C++ 功能都公开为“C”风格的函数。确保将该函数声明为 _stdcall。

extern "C" __declspec(dllexport) int _stdcall Foo(int a)

extern "C" __declspec(dllexport) int _stdcall Foo(int a)

Make sure you get the marshalling right, especially things like pointers & wchar_t *. If you get it wrong, it can be difficult to debug.

确保你的编组正确,尤其是像指针和 wchar_t * 这样的东西。如果弄错了,可能很难调试。

Debug it from either side, but not both. When debugging mixed native & managed, the debugger can get very slow. Debugging 1 side at a time saves lots of time.

从任一侧调试它,但不能同时调试。在调试混合本机和托管时,调试器会变得非常慢。一次调试一侧可以节省大量时间。

Getting more specific would require a more specific question.

变得更具体需要一个更具体的问题。

回答by Alan

I would take a look at swig, we use this to good effect on our project to expose our C++ API to other language platforms.

我会看看swig,我们使用它对我们的项目产生良好的效果,将我们的 C++ API 暴露给其他语言平台。

It's a well maintained project that effectively builds a thin wrapper around your C++ library that can allow languages such as C# to communicate directly with your native code - saving you the trouble of having to implement (and debug) glue code.

这是一个维护良好的项目,它有效地围绕您的 C++ 库构建了一个瘦包装器,它可以允许 C# 等语言直接与您的本机代码进行通信 - 为您省去必须实现(和调试)胶水代码的麻烦。

回答by Alex Reitbort

If you want a good PInvoke examples you can look at PInvoke.net. It has examples of how to call most of win api functions.

如果您想要一个好的 PInvoke 示例,您可以查看PInvoke.net。它有如何调用大多数 win api 函数的示例。

Also you can use tool from this article Clr Inside Out: PInvokethat will translate your .h file to c# wrappers.

您也可以使用这篇文章Clr Inside Out: PInvoke中的工具将您的 .h 文件转换为 c# 包装器。

回答by stephbu

Of course there is always PInvoke out there too if you packaged your code as DLLs with external entrypoints. None of the options are pain free. They depend on either a) your skill at writing COM or Managed C wrappers b) chancing your arm at PInvoke.

当然,如果您将代码打包为带有外部入口点的 DLL,那么总是有 PInvoke 存在。没有一个选项是无痛的。它们取决于 a) 您在编写 COM 或托管 C 包装器方面的技能 b) 在 PInvoke 上碰碰运气。

回答by 1800 INFORMATION

You can also call into unmanaged code via P/Invoke. This may be easier if your code doesn't currently use COM. I guess you would probably need to write some specific export points in your code using "C" bindings if you went this route.

您还可以通过 P/Invoke 调用非托管代码。如果您的代码当前不使用 COM,这可能会更容易。我想如果你走这条路,你可能需要使用“C”绑定在你的代码中编写一些特定的导出点。

Probably the biggest thing you have to watch out for in my experience is that the lack of deterministic garbage collection means that your destructors will not run when you might have thought they would previously. You need to keep this in mind and use IDisposable or some other method to make sure your managed code is cleaned up when you want it to be.

根据我的经验,您需要注意的最重要的事情可能是缺乏确定性垃圾收集意味着您的析构函数将不会像您之前认为的那样运行。您需要牢记这一点并使用 IDisposable 或其他一些方法来确保您的托管代码在您需要时被清理。