创建可以从 c# 和 c++ 中使用的 c# dll

Posted

技术标签:

【中文标题】创建可以从 c# 和 c++ 中使用的 c# dll【英文标题】:create c# dll which can be used from both c# and c++ 【发布时间】:2013-06-27 10:14:38 【问题描述】:

我正在将我的解决方案从 c# 迁移到 c++。我已经创建了几个本机 c++ dll,它们都很好。将本机 dll 连接到 c++ 和 c# 很容易。对于 c#,我使用 P/Invoke 执行方法,使用 delegate 进行回调,我只是将指针传递给非托管内存并使用 Marshall 类读取它。

现在我有相反的情况 - 我需要创建 C# 项目,现在将在另一个 C# 项目中使用,但稍后我会将主项目重写为 C++,因此我需要从 C++ 访问 C# 项目。它应该只提供几种方法:PlaceOrder(void* pointerToStruct)CancelOrder(void* pointerToStruct) 和一个回调delegate OrderUpdated(void* pointerToStruct)

我正在寻找提示和示例。如何创建可以从原生 C++ 和 C# 使用并提供多种方法 + 一个回调的 C# 项目。

特别是我现在不知道我应该如何处理内存 - 我应该在 c# 中写入非托管内存并在 c++ 中读取它,还是应该在 c# 中写入托管内存并以某种方式在 c++ 中读取托管内存...指向我在参数中传递的结构的指针应该指向非托管内存或托管内存等。

【问题讨论】:

你几乎不能创建 dll 导出表(除非你在 IL 或托管 C++ 中创建);也许创建 COM 更容易? COM 缓慢而复杂,我正在编写低延迟软件,它只是临时解决方案,所以我更喜欢简单快速的东西。 我有 c# 部分,我不需要重写为 c++。因为一旦移植到linux,我就会把它扔掉。但在那之前我需要使用 c++ 中的 c#。 一般来说,COM 调用并不比对 dll 中的 C 方法的普通调用慢(在此上下文中),并且并不比使用类复杂多少。但是,即使是这样,我也看不出它与临时解决方案有什么关系。除非你能证明显着差异,否则我会说 COM 是最好的方法。 arg/return value marshalling 必须在这两种情况下进行,并且很容易花费大部分时间来执行调用。 【参考方案1】:

您可能希望创建 COM 组件:Create COM component and ActiveX controls in .Net

如果你是在Windows8下开发,你可能会想到创建Windows Component:

Creating Windows Runtime Components in C#

【讨论】:

【参考方案2】:

用C#写的dll的问题是无法制作导出表(将静态方法标记为正在导出): 有 DllImportAttribute 但在 C# 中没有 DllExportAttribute。不过有两种方法:

    在专为此目的设计的托管 C++ 上(至少部分地)编写 dll。 C#源代码编译后更改生成的IL: 例如http://winch.pinkbile.com/wiki/index.php/Main/Dlltool http://www.codeproject.com/Articles/37675/Simple-Method-of-DLL-Export-without-C-CLI

另见

Is is possible to export functions from a C# DLL like in VS C++?

【讨论】:

这些选项中哪个具有更好的延迟?我应该在VS,C#“类库”中创​​建什么类型的项目? sites.google.com/site/robertgiesecke/Home/uploads/… 呢? 两个选项都具有低延迟,更改 IL 会稍微好一些。 我们只需要在生成的 IL 中做一个小改动,很多库都可以做到(Nuget 就是其中之一)。 关于 codeproject 参考,我发现“生成的程序集将仅是 32 位。”,对我不起作用。将检查 dlltool 是否支持 64 位。你能推荐一些最新的东西来保证与 VS2012 和 64 位一起工作吗?

以上是关于创建可以从 c# 和 c++ 中使用的 c# dll的主要内容,如果未能解决你的问题,请参考以下文章

在同一解决方案中从 c# 项目到 c++ 项目的 DllImport

在 C++ DLL 和 C# 类之间来回传递变量

是否可以在 C# 中从本机 C++ 类创建变量?

从 C# 中的 C++ 代码中获取对象功能

如何从 CUDA C++ 创建和使用动态库“.so”并在 Linux 环境 (CentOS) 下的 C# 代码中使用它?

从 C# 调用 C++ 代码而不创建 dll?