最佳实践是部分更改c++库,同时保持库的其余部分不变
Best practice to partially change a C++ library while keeping the rest of the library intact
在完善的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上有更多关于代理模式的信息,可以帮助您入门。
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在c代码之间共享数据的最佳方式
- 使用std::source_location报告错误的最佳实践
- 派生类销毁的最佳实践是什么
- 将寄存器设计成可由C和C++访问的外设的最佳实践
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 检测win32服务创建和删除的最佳方法
- 在reactor中存储eventHandlers的最佳方式是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 在AVX通道中混洗的最佳方式
- 程序顶部的声明与定义(最佳实践)
- 别名模板的专业化 C++11 中没有开销的最佳替代方案