11

What is the best practice to add or modify a single class method in a well-established C++ library like OpenCV, while still reusing the remaining of the library code, preferably in the lib format.

At this point the only way I know is to copy all the source and header files that belong to the specific library (let's say OpenCV's core library) to the current source folder, modify that one function and recompile the module with the rest of the code. Ideally, I want to be able to link all the current .lib files the way they are, but simply define a new method (or modify a current method) for a class defined inside those libs in a way that my implementation of the method supersedes the implementation of the default library files.

Inheritance doesn't always seem to be an option, since sometimes the base class has private members that are required for the correct inherited class implementation.

4

3 に答える 3

9

I'm not aware of a clean way in C++ to accomplish what you're asking. What you're really asking to do (given that you need to use or modify private methods) is violate encapsulation, and the C++ language is designed to not let you do that.

A few options exist:

  • A .lib file is simply a collection of .obj files. Your compiler toolchain should have a command-line program for adding, deleting, and replacing .obj files in a .lib, so you could build one or two .obj files and merge them into the .lib. I suspect that this solution would be ugly and fragile.
  • If there's something that the library doesn't do and should do, then there's always a chance that you can submit a patch or feature request to the library authors to get that change made. Of course, this can take a while, if it works at all.
  • As @fatih_k suggests, adding your changes as friend classes would work. If the only change you make to OpenCV is to add a friend line to the header file, then the library's ABI will be unchanged, and you won't have to touch the .lib.
  • The cleanest option is to simply accept that you need to modify the OpenCV library and track its source code, along with your modifications, along with the source code you develop yourself, and build it along with the source code you build yourself. This is a very common approach, and various patterns and techniques exist to help you do it; for example, Subversion has the concept of vendor branches. This approach is more work to set up but is definitely the cleanest in the long run.
于 2013-03-26T15:27:58.543 に答える
4

If the library is already compiled, there is not much you can do portably and cleanly.

If you know the specific target architecture the program will be runnning on, you could get the pointer to the member function and monkey patch the instructions with a jmp instruction to your own version of the method. If the method is virtual, you can modify the vtable. Those requires a lot of compiler-specific knowledge and would not be portable.

If the library ships in dynamic link archive, you could extract the archive and replace the method with your own version, and repack the archive.

Another method is you can copy the class' declaration from the header and add a friend declaration. Alternatively, you can do #define private public or #define private protected before including a header file. These will give you access to their private members.

With any of the above, you need to be careful that your changes does not modify the ABI of the library.

于 2013-03-26T15:28:47.423 に答える
1

Well, OpenCV is licensed under BSD so you can make your changes without worries about republishing them.

You could always follow the Proxy design pattern and add the new method external to the library, and call into the library from there. That means you don't need to worry about maintaining your own version of OpenCV and distributing it as well. There's more information about Proxy patterns on Wiki to get you started.

于 2013-03-26T15:21:31.483 に答える