如何在C++;? 在C++中实现猴子补丁是可能的吗? 或者其他类似的方法 谢谢。< /P> AS是指动态改变代码,我无法想象如何在C++中实现这一点…p>

如何在C++;? 在C++中实现猴子补丁是可能的吗? 或者其他类似的方法 谢谢。< /P> AS是指动态改变代码,我无法想象如何在C++中实现这一点…p>,c++,C++,我想这取决于你想做什么。如果你已经链接了你的程序,你将很难替换任何东西(除了实际更改内存中的指令,这可能也是一个延伸)。然而,在这种情况发生之前,有一些选择。如果您有一个动态链接的程序,您可以更改链接器的操作方式(例如,LD_LIBRARY_PATH环境变量),并让它链接预期库以外的其他内容 查看ValGRIN,它取代了(在其他许多魔法方面处理的)标准内存分配机制。 < P>考虑到“游击第三方库使用”的猴子补丁方面,C++提供了许多设施: const\u cast允许您处理热心的const声明

我想这取决于你想做什么。如果你已经链接了你的程序,你将很难替换任何东西(除了实际更改内存中的指令,这可能也是一个延伸)。然而,在这种情况发生之前,有一些选择。如果您有一个动态链接的程序,您可以更改链接器的操作方式(例如,LD_LIBRARY_PATH环境变量),并让它链接预期库以外的其他内容

查看ValGRIN,它取代了(在其他许多魔法方面处理的)标准内存分配机制。

< P>考虑到“游击第三方库使用”的猴子补丁方面,C++提供了许多设施:

  • const\u cast
    允许您处理热心的
    const
    声明
  • #在头包含之前定义私有-公共
    允许您访问私有成员
  • 子类化和
    使用Parent::protected_字段
    可以访问受保护的成员
  • 您可以在链接时重新定义许多内容

如果你正在工作的第三方内容已经被编译,但是,在动态语言中可行的大多数事情都不是那么容易,而且通常是不可能的。

< p>要添加其他答案,可以考虑通过共享对象或DLL(取决于平台)公开的任何函数都可以在运行时重写。Linux提供了
LD_PRELOAD
环境变量,该变量可以指定一个要在所有其他对象之后加载的共享对象,该对象可用于覆盖任意函数定义。这实际上是为单元测试目的提供“模拟对象”的最佳方式,因为它不是真正的入侵性。然而,与其他形式的猴子修补不同,请注意这样的变化是全球性的。您不能将一个特定调用指定为不同的,而不影响其他调用。

不可移植,而且由于大型项目的危险,您最好有充分的理由

预处理器可能是最好的选择,因为它不了解语言本身。它可以用于重命名属性、方法和其他符号名称,但替换是全局的,至少对于单个#include或代码序列是如此

我曾经用它来击败“库钻石”来提交-库A和库B都导入了OS库S,但方式不同,因此S的一些符号的名称相同但不同。(名称空间是不可能的,因为它们会产生更深远的影响)

同样,可以用兼容但更高级的类替换符号名称。 e、 g.在VC中,
#import
生成一个导入库,该库使用
\u bstr\t
作为类型适配器。在一个项目中,我成功地用一个足够兼容的类替换了这些使用,该类可以更好地与其他代码进行互操作,只需将
\define
'ing
\u bstr\t
定义为
\import
的替换类即可

修补虚拟方法表——替换整个VMT或单个方法——是我遇到的另一件事。它需要很好地理解编译器如何实现VMT。我不会在实际项目中这样做,因为它依赖于编译器内部,而且当事情发生变化时,您不会得到任何警告。不过,学习C++的实现细节是一个有趣的练习。一个应用程序将在运行时从初始值设定项/加载程序存根切换到完整的(甚至依赖于数据的)实现


动态生成代码在某些场景中很常见,例如转发/过滤COM接口调用或将操作系统窗口句柄映射到库对象。我不确定这是否仍然是“猴子补丁”,因为它并不是真的在玩弄语言本身。

是否有一个特定的词来形容猴子补丁中不太活跃的那一半?诸如const_cast、访问控制重新定义和RTTI滥用之类的东西?至于依赖于编译器内部,当情况发生变化时,您可能会收到警告——只需将所需的断言构建到单元测试中即可。这在实践中对我很有效(不是vtable补丁,而是在其他情况下,我试图编写依赖于特定STL实现方面的代码)。