gpt4 book ai didi

c++ - Shell 扩展 : Static-Linking vs. C/C++ 运行时 DLL 的动态链接

转载 作者:行者123 更新时间:2023-11-30 01:57:38 33 4
gpt4 key购买 nike

在构建 Windows 资源管理器shell 扩展(当前使用 VS2010 SP1)时,您是否建议静态链接(到 CRT、C++ 运行时和其他支持库,如 ATL ) 或动态链接

static-linking 选项的好处之一是使部署更容易(事实上,这样,就可以只部署 shell 扩展-proc COM 服务器 DLL,不依赖于其他 C/C++ 运行时 DLL。

如果是动态链接msvcr100.dllmsvcp100.dllWindows\System32 中的 DLL 由 shell 扩展使用,好处是如果 Microsoft 修复了这些 DLL 中的某些内容(例如安全修复),这些修复自动由自定义 shell 扩展使用.
然而,糟糕的是,那些“全局”修复也可能会在相关代码中引入错误和破坏东西。

至于 VCRedist DLL 的 app-local 部署,我不确定它在 shell 扩展的情况下如何工作。应该在 shell 扩展 COM DLL 中嵌入什么样的 list 来引用 shell 扩展文件夹下的 VCRedist DLL?

最佳答案

当多个模块相互交互时,必须使用 CRT 的 DLL 版本通常是一个非常困难的要求。一个特别重要的方面是在所有模块中使用相同的分配器。这样在一个模块中分配的对象可以被另一个模块中的代码安全地销毁。这在 C++ 中经常出现,做一些像从函数返回 std::string 这样简单的事情是非常麻烦的。它在被调用者中创建,需要在调用者中销毁。如果跨模块边界进行函数调用并且两个模块使用不同的堆,就会发生灾难。

标准 C++ 对象的布局也与 CRT 实现相关联。不同版本的编译器使用不同的 std::string 实现。如果一个模块使用与另一个模块不同的实现,调用者根本无法正确使用被调用者创建的对象,就会发生灾难。即使像调试设置这样简单的事情也可能导致不匹配,Microsoft CRT 中的迭代器调试支持尤其因导致不匹配而臭名昭著,它使 STL 对象变得更大。

然而,这些问题在 COM 中是可以避免的。有一个强大的内存管理协议(protocol),基于 IUnknown 接口(interface)的 AddRef 和 Release 方法。这使得对象的创建者始终是对象的所有者并负责销毁它。其他分配,如 BSTR 和 SAFEARRAY,必须始终从保证在进程内共享的堆中进行。 CoTaskMemAlloc、CoTaskMemFree 和 IMalloc 实现了该管道。

而且它强烈避免了对象布局问题,COM 严格只与接口(interface)一起工作。严格禁止跨互操作边界传递 C++ 对象或异常之类的操作。唯一的实现细节是调用约定,严格的 __stdcall 和接口(interface) v-table 布局,严格绑定(bind)到接口(interface)的 IID。更改接口(interface)需要选择一个新的 IID。

长话短说,因此您根本不需要使用 CRT 的共享版本。事实上,许多 COM 服务器都是使用/MT 编译的。使用/MD 也很好,如果您的 COM 服务器本身是使用多个模块实现的,您只会考虑它。

关于c++ - Shell 扩展 : Static-Linking vs. C/C++ 运行时 DLL 的动态链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18485805/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com