代码之家  ›  专栏  ›  技术社区  ›  Adam Holmberg

C++ COM C混合模式互操作

  •  2
  • Adam Holmberg  · 技术社区  · 15 年前

    我试图理解我从非托管C++调用C.*库实现的选项。

    我的顶层模块是一个非托管C++ COM/ATL DLL。我想集成现有托管C_dll的功能。我有,并且可以重新编译两个库的源代码。

    我从阅读诸如 this overview 关于MSDN和 this SO question 可能会创建一个“混合模式”DLL,允许本地C++代码调用C语言库。

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

    1. 我该怎么设置呢? 我能简单地更改一些属性吗 在现有的COM/ATL项目上 允许使用C模块?
    2. 这些混合模式的电话怎么打 与COM互操作的性能不同 电话?有公共字符串吗 可用于阻止的格式 转换或深度复制 模块?
    3. 如果创建了此dll 混合模式,还能吗 接口/使用方式相同 它的COM客户端,或者他们需要 了解混合模式?
    4. 是否将clr包含在 加载此COM对象时的开销?

    我不熟悉Windows开发,所以如果问题陈述中的任何内容需要澄清或更正,请发表评论。

    事先谢谢。

    2 回复  |  直到 15 年前
        1
  •  4
  •   Pavel Minaev    15 年前

    我该怎么设置呢?我可以简单地更改现有COM/ATL项目的一些属性以允许使用C模块吗?

    如果您完全控制了该项目,那么更改此类设置不是问题,那么当然可以。你只需要启用 /clr 对于此项目(在项目属性中,打开“常规”页,并查找“公共语言运行时”支持)。现在可以使用托管句柄( ^ 和项目中的其他C++/CLI位。所有在普通C++中编写的代码应该继续工作(它将被编译成MSIL,尽可能多,但是它的语义将保持不变)。

    这些混合模式调用在性能上与COM互操作调用有何不同?是否存在可用于防止模块之间转换或深度复制的通用字符串格式?

    混合模式调用将更快,因为它使用更快的调用约定,并且不会像COM互操作那样执行任何封送(您要么使用固有兼容的类型,要么执行自己的显式转换)。

    没有常见的字符串格式-问题是 System::String 同时分配和拥有它的缓冲区,还要求它是不可变的;因此您不能自己创建缓冲区,然后将其包装为 String 或创建一个 然后使用它作为缓冲区将文本输出到。

    如果此dll是创建的混合模式,它的COM客户端是否仍可以以相同的方式进行接口/使用,还是需要知道混合模式?

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

    在加载这个COM对象时,包含clr会产生很大的开销吗?

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

    在任何情况下,加载clr意味着您将获得所有GC和JIT机器。这些不便宜。也就是说,如果最终需要调用托管代码,就没有办法解决这个问题——您将 将CLR加载到某个进程中以执行此操作。COM互操作和混合模式C++/CLI程序集之间的惩罚不会有所不同。

        2
  •  0
  •   Thomas Weller    15 年前

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

    但是,只要让vs向导为您创建一个代理,您就可以轻松地使用任何C代码中的任何COM接口,除了调用com和.net时一直具有的性能开销外,它没有任何性能开销。

    另一个方向,你只需要设置你的组件 ComVisibleAttribute 如果为true(在vs中,它是项目属性中的一个简单复选框),那么编译器将自动为您创建COM接口。同样,没有额外的性能惩罚。

    嗯!

    推荐文章