我该如何设置呢?我可以简单地更改现有 COM/ATL 项目的一些属性以允许使用 C# 模块吗?
如果您完全控制该项目,那么更改此类设置不是问题,那么可以确定。您只需要启用/clr此项目(在项目属性中,打开“常规”页面,并查找“公共语言运行时”支持)。现在,您可以根据需要在项目中使用托管句柄 ( ^) 和其他 C++/CLI 位。所有用纯 C++ 编写的现有代码都应该继续工作(它现在将尽可能编译为 MSIL,但其语义将保持不变)。
这些混合模式调用与 COM 互操作调用的性能有何不同?是否有一种通用的字符串格式可用于防止模块之间的转换或深度复制?
混合模式调用会更快,因为它使用更快的调用约定,并且不会像 COM 互操作那样进行任何封送处理(您要么使用本质上兼容的类型,要么进行自己的显式转换)。
没有通用的字符串格式——问题是System::String既分配又拥有它的缓冲区,并且还要求它是不可变的;因此您不能自己创建缓冲区然后将其包装为String,或者创建 aString然后将其用作缓冲区以将文本输出到。
如果这个 dll 是在混合模式下创建的,它的 COM 客户端是否仍然可以以相同的方式接口/使用它,或者它们是否需要了解混合模式?
它可以有相同的接口,但如果它是通过本机入口点进入的,它将尝试将 CLR 加载到进程中,除非已经加载了一个。如果调用客户端在调用之前已经加载了 CLR(或者客户端本身是从托管代码调用的),那么您将获得已经加载的 CLR,这可能与您的代码所需的 CLR 不同(例如客户端可能已经加载了 1.1,而您的代码需要 2.0)。
加载此 COM 对象时,包含 CLR 是否会产生大量开销?
这取决于您对开销的定义。代码大小?运行时惩罚?内存占用?
无论如何,加载 CLR 意味着您获得了所有 GC 和 JIT 机器。那些都不便宜。也就是说,如果您最终需要调用托管代码,则无法解决此问题 - 您必须将 CLR 加载到某个进程中才能执行此操作。COM Interop 和混合模式 C++/CLI 程序集之间的惩罚不会有所不同。