我正在尝试了解我从不受管理的C ++调用C#库实现的选项。

我的顶级模块是一个非托管的C ++ COM/ATL DLL。我想整合现有的托管C#DLL的功能。我有,并且可以重新编译两个库的来源。

我从阅读文章中了解 此概述 在MSDN和 这个问题 可以创建一个“混合模式” DLL,该DLL允许本机C ++代码拨打C#库。

我对这种方法有几个问题:

  1. 我该如何进行设置?我可以简单地更改现有COM/ATL项目上的一些属性以允许使用C#模块吗?
  2. 这些混合模式调用的性能与COM Interop调用有何不同?是否可以使用通用的字符串格式来防止模块之间的转换或深拷贝?
  3. 如果创建此DLL混合模式,是否可以通过其COM客户端以相同的方式将其连接/使用,或者需要混合模式知道?
  4. 加载此COM对象时,包含CLR会施加大量的开销吗?

我是Windows开发的新手,因此,如果问题声明中的任何内容需要澄清或更正,请评论。

提前致谢。

有帮助吗?

解决方案

我该如何进行设置?我可以简单地更改现有COM/ATL项目上的一些属性以允许使用C#模块吗?

如果您完全控制该项目,因此更改此类设置不是问题,请肯定。您需要的只是启用 /clr 对于此项目(在项目属性中,打开“常规”页面,并寻找“通用语言运行时”支持)。现在您可以使用托管手柄(^)和您项目中的其他C ++/CLI位。所有用普通C ++编写的现有代码都应继续工作(现在将尽可能地汇编给MSIL,但其语义将保持不变)。

这些混合模式调用的性能与COM Interop调用有何不同?是否可以使用通用的字符串格式来防止模块之间的转换或深拷贝?

混合模式调用将更快,因为它使用更快的呼叫约定,并且不会对COM Interop的操作方式进行任何宣传(您要么使用固有兼容的类型,要么进行自己的显式转换)。

没有常见的字符串格式 - 问题是 System::String 分配并拥有其缓冲区,还要求它是不变的。因此,您无法自己创建缓冲区,然后将其包裹为 String, ,或创建一个 String 然后将其用作缓冲区以输出文本。

如果创建此DLL混合模式,是否可以通过其COM客户端以相同的方式将其连接/使用,或者需要混合模式知道?

它可以连接相同,但是如果它是通过本机入口点输入的,则它将尝试将CLR加载到该过程中,除非已经加载了CLR。如果调用客户端在呼叫之前已经加载了CLR(或者客户本身是从托管代码调用的),那么您将获得已加载的CLR,这可能与您的代码所需的CLR不同(例如客户端可能已加载1.1,您的代码需要2.0)。

加载此COM对象时,包含CLR会施加大量的开销吗?

这取决于您通过开销定义的内容。代码大小?运行时处罚?内存足迹?

无论如何,加载CLR意味着您可以获得所有GC和JIT机械。这些并不便宜。也就是说,如果您最终需要调用托管代码,无论如何都无法解决 - 您将 将CLR加载到某个过程中。 COM Interop和混合模式C ++/CLI组件之间的惩罚不会有所不同。

其他提示

我不能对诸如字符串问题之类的细节说太多,因为我从未积极使用这种方法。

但是,您可以通过简单地让vs向导为您创建代理,从而轻松地使用任何C#代码的COM接口,除了调用COM和.NET时始终具有的性能开销。

另一个方向,您只需要设置C#组件' ComVisibleAttribute 真实(在VS中,这是项目属性中的一个简单复选框),然后编译器将自动为您创建COM接口。同样,没有其他绩效罚款。

恩!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top