如何使用 C++来自 C# 和 .NET 的库?
我的问题与 DLL 如何导出 C++ 类和泛型方法(关于没有 C# 并行的 C++ 语言功能)密切相关。
我相信您可以通过引用 DLL 并使用 DLLImport 从 C# 调用 extern "C" 块内的函数。但是您可以实例化模板化的 C++ 类型吗?如果 C++ 类型做了 C# 不支持的一些疯狂的事情怎么办?是否有 RFC 或 C# 规范< /a>?
谢谢...
编辑:我现在偶然发现了 P/Invoke 这应该很有价值,但我我仍在寻找与此相关的规范或标准。
My question is closely related to how a DLL exports C++ classes and generic methods (wrt C++ language features without a C# parallel).
I believe you can call functions inside an extern "C"
block from C# by just referencing the DLL and using DLLImport. But can you instantiate a templated C++ type? What if the C++ type does somethin' crazy that's not supported in C#? Is there an RFC or relevant part of the C# specification?
Thanks...
EDIT: I now stumbled across P/Invoke which should be valuable, but I'm still looking for a specification or standard regarding this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
明智的方法是使用托管 C++ 访问非托管 C++ 并编译成程序集。
The sane way to do it is to use managed c++ to access unmanaged c++ and compile into an assembly.
错误,您必须使用
DllImport
或所谓的 PInvoke (平台调用)从托管代码调用本机 C 函数。引用仅适用于具有自动生成的互操作 DLL 的 .NET 程序集或 COM。
由于名称损坏等问题,从 C# 使用 C++ 变成了一场真正的噩梦。
如果可以的话,您可以将托管 C++ Dll 编译为包装器,以使两个世界相遇。这还有一个优点,您可以将程序集标记为
ComVisible
,从而使其可供许多能够处理 COM 的工具使用。另一种方法是围绕 C++ API 编写 C 包装器,这可能既乏味又丑陋。
编辑:
帮助决定使用哪种方法:
Wrong, you have to use
DllImport
or so-called PInvoke (Platform Invoke) to call a native C function from managed code. Referencing works only for .NET assemblies or COM with an automatically generated interop dll.Using C++ from C# becomes a real nightmare because of name mangling among other things.
If you can you could compile a managed C++ Dll as a wrapper to make both worlds meet. This has also the advantage that you can mark your assembly as
ComVisible
, thus making it available to plenty of tools capable of handling COM.An alternative is to write a C wrapper around the C++ API, what can be tedious and ugly.
EDIT:
Help to decide which approach to use:
就 C# 而言,DLL 内部所做的事情是无关紧要的。请记住,C++ 模板在实例化之前不会生成任何代码。如果模板只是在 DLL 头文件中的某处定义,则 DLL 中不会为该模板生成任何代码。另一方面,如果 DLL 显式实例化并导出某些模板化类型,那么理论上您可以从 C# 调用它们。
您必须克服两个问题。第一个是 C++ 编译器会破坏它们的方法名称,因此您必须准确地弄清楚 PInvoke 的正确名称是什么。第二个问题是无法直接在 C# 中创建 CRT 对象。您必须定义一些工厂方法并导出它们。
坦率地说,我认为这比它的价值更麻烦。您最好为 DLL 创建 C 风格的 API 并从 C# 调用这些函数。在内部,这些函数可以创建和操作相关的 C++ 对象。
What the DLL does internally is irrelevant, as far as C# is concerned. Keep in mind that C++ templates do not generate any code until the template is instantiated. If the template is simply defined somewhere in the DLL header files, then there won't be any generated code for that template in the DLL. On the other hand, if the DLL explicitly instantiates and exports some templated types, then you could theoretically call them from C#.
There are two issues you'd have to overcome. The first is that C++ compilers mangle their method names, so you'd have to figure out exactly what the proper name to PInvoke is. The second problem is that there's no way to create CRT objects in C# directly. You'd have to define some factory methods and export those as well.
Frankly, I think this is all way more trouble than its worth. You'd be better off creating a C-style API for the DLL and calling those functions from C#. Internally, the functions could create and manipulate the relevant C++ objects.