C++ 在使用不同visual studio编译器版本编译的进程中加载COM

C++ 在使用不同visual studio编译器版本编译的进程中加载COM,c++,visual-studio-2010,com,runtime,C++,Visual Studio 2010,Com,Runtime,我们有一个使用VisualStudio2008版本编译的可执行文件。由于第三方的依赖性,我们必须在VisualStudio2008中编译此可执行文件 我们还有另一个在VisualStudio2010中编译的组件。现在我们需要从这个组件(在2010编译器版本中编译)获取一个COM组件dll,该组件由使用2008编译器版本编译的可执行文件访问 我的问题是,它能正常工作吗。可执行文件使用的运行时(即2008运行时库)和COM组件使用的运行时(即使用2010运行时)是否存在冲突 实际上,我们尝试在可执行

我们有一个使用VisualStudio2008版本编译的可执行文件。由于第三方的依赖性,我们必须在VisualStudio2008中编译此可执行文件

我们还有另一个在VisualStudio2010中编译的组件。现在我们需要从这个组件(在2010编译器版本中编译)获取一个COM组件dll,该组件由使用2008编译器版本编译的可执行文件访问

我的问题是,它能正常工作吗。可执行文件使用的运行时(即2008运行时库)和COM组件使用的运行时(即使用2010运行时)是否存在冲突

实际上,我们尝试在可执行文件中加载这个COM dll,但实际上效果很好。但我担心在以后的时间里,由于多次运行,它可能会崩溃/失败

请让我知道在这里如何处理多个运行时。在单个可执行文件中加载不同的运行时是否安全。由于可用的运行时不同,在执行的后期会有任何冲突吗

无论如何,一个解决方案,我们正在寻找解决这个问题,使COM组件作为一个OUT-proc服务器,这无论如何将工作。但这需要做很多工作

请让我知道


非常感谢

混合与不同运行时库链接的COM对象应该不会有问题,因为每个对象的内存分配和释放都将在DLL边界之后完成


您需要注意的是,所有方法都有正确的COM签名,即所有指针都应该是COM指针。

COM是为二进制互操作而设计的。从设计上看,该框架与实现无关。其目的是COM服务器可以用一种语言/运行时实现,并由使用不同语言/运行时实现的COM客户端使用


对于各方使用的语言和运行时,绝对没有任何限制

这一点已经在多个上下文中得到了多次回答

只要不在模块之间处理和/或传递C运行时(CRT)数据结构,就可以了。如果在依赖于不同CRT的模块之间执行以下任一操作,您将遇到问题,在这种特定情况下,您没有正确实现COM对象:

  • 一个模块中的
    malloc
    内存和另一个模块中的
    realloc
    free
  • fopen
    a
    文件*
    在一个模块中,而
    fread
    fwrite
    fclose
    等在另一个模块中
  • setjmp
    在一个模块中,而
    longjmp
    在另一个模块中
请注意,您可以执行以下操作:

  • 使用另一个模块分配的内存
    malloc
    ,负责重新分配和释放原始模块
  • 使用一些与另一个模块生成的文件
    fopen
    交互的接口,将其使用责任保留在原始模块上
  • 不要在不相关或耦合不紧密的模块之间使用
    setjmp
    /
    longjmp
    ,定义回调、中止错误代码等等,但不要依赖解缠技术,即使是由操作系统提供的
你可以在这里看到一种模式。您可以使用另一个模块中的资源,只要您将管理这些资源的任务委托给该模块


使用COM,您不应该遇到这种问题,所有东西都应该通过实现的接口封装在对象中。尽管您可以将
malloc
ed内存作为顶级指针参数传递,但您只能访问被调用方中的该内存,而不能重新分配或释放它。对于内部指针,必须使用
CoTaskMemAlloc
及其近亲,因为这是COM中的常见内存管理器。这适用于处理文件(例如,将它们封装在
IStream
IPipeByte
、一个
IEnumByte
或类似文件中),并且不要跨COM调用展开。但是COM的设计是为了让客户端甚至不关心对象是在进程内,还是在进程外,甚至是在远程机器上。最大的暴行发生在进程内COM中,因此我将重点放在这一点上。进程间或远程
文件*
注定会失败,所以是的,对于进程外,使用哪个CRT根本不重要。