最佳实践是部分更改c++库,同时保持库的其余部分不变

Best practice to partially change a C++ library while keeping the rest of the library intact

本文关键字:余部 最佳 c++      更新时间:2023-10-16

在完善的c++库(如OpenCV)中添加或修改单个类方法,同时仍然重用库代码的剩余部分(最好是lib格式)的最佳实践是什么?

在这一点上,我知道的唯一方法是将所有属于特定库(假设是OpenCV的核心库)的源和头文件复制到当前源文件夹,修改该函数并使用其余代码重新编译模块。理想情况下,我希望能够按原样链接所有当前.lib文件,但只需为这些库中定义的类定义一个新方法(或修改当前方法),以一种方法的实现取代默认库文件的实现。

继承似乎并不总是一个选项,因为有时基类具有正确继承类实现所需的私有成员。

我不知道c++中有什么干净的方法来完成你所要求的。你真正要求做的(考虑到你需要使用或修改私有方法)是违反封装的,而c++语言的设计不允许你这样做。

有以下几个选项:

  • .lib文件只是.obj文件的集合。您的编译器工具链应该有一个命令行程序,用于在.lib中添加、删除和替换.obj文件,因此您可以构建一个或两个.obj文件并将它们合并到.lib中。我怀疑这个解决方案既丑陋又脆弱。
  • 如果有一些库没有做而应该做的事情,那么你总是有机会向库作者提交补丁或功能请求来进行更改。当然,这可能需要一段时间,如果它工作的话。
  • 正如@fatih_k建议的那样,将您的更改添加为好友类将有效。如果您对OpenCV的更改是在头文件中添加friend行,那么库的ABI将保持不变,并且您不必触及.lib
  • 最干净的选择是简单地接受您需要修改OpenCV库并跟踪其源代码,以及您的修改,以及您自己开发的源代码,并与您自己构建的源代码一起构建它。这是一种非常常见的方法,有各种模式和技术可以帮助您做到这一点;例如,Subversion有供应商分支的概念。这种方法需要更多的工作来设置,但从长远来看绝对是最干净的。

如果库已经编译过了,那么您就不能做太多可移植且干净的工作了。

如果你知道程序将要运行的特定目标体系结构,你可以获得指向成员函数的指针,然后用jmp指令将指令修补到你自己的方法版本。如果方法是虚方法,则可以修改虚函数表。这些需要大量编译器相关的知识,并且不具有可移植性。

如果库附带了动态链接归档,您可以提取归档并将方法替换为您自己的版本,并重新打包归档。

另一种方法是从头文件中复制类的声明,并添加友元声明。或者,您可以在包含头文件之前执行#define private public#define private protected。这将允许您访问它们的私有成员。

使用上述任何一种方法,您都需要注意您的更改不会修改库的ABI。

嗯,OpenCV是在BSD下许可的,所以你可以做你的更改而不用担心重新发布它们。

您总是可以遵循Proxy设计模式并在库外部添加新方法,然后从那里调用库。这意味着您不需要担心维护自己的OpenCV版本和分发它。在Wiki上有更多关于代理模式的信息,可以帮助您入门。