C ++ Wrap Pattern

I am trying to wrap a template function using the GNU link transfer option. The code is as follows:

// fh template<typename T> void f(T t) { } // bar.h void bar(); // bar.cpp #include "bar.h" #include "fh" void bar() { f(42); } // test.cpp extern "C" { extern void __real__Z1fIiEvT_(int i); void __wrap__Z1fIiEvT_(int i) { __real__Z1fIiEvT_(i); } } int main() { bar(); } 

The code shown above is associated with the following command:

 g++ -Xlinker -wrap=_Z1fIiEvT_ -o test test.o bar.o 

Unfortunately, this does not work and the original function f is always called instead of my wrapped version __wrap__Z1fIiEvT_. Do you see the mistakes I made?

Edited: As recommended, I am adding nm output here to make sure that I have not made any errors with the changed template function name:

 $ g++ -c bar.cpp -o bar.o $ nm bar.o 0000000000000000 W _Z1fIiEvT_ 
+6
source share
2 answers

From http://linux.die.net/man/1/ld :

- wrap = symbol
Use the wrapper function for the character. Any undefined reference to a symbol will be resolved to "_wrap symbol". Any undefined reference to "_real symbol" will be resolved to the symbol.

I think the word "undefined" may be the key here. Your character of interest is definitely defined in bar.o, and the nm output confirms it, because undefined characters are marked with a "U", not a "W".


Update:

I think it's therefore not possible to wrap template functions?

I think it depends more on where the function is defined (or created), and if that definition is available to the linker. In your case, if you defined a function without a template in bar.cpp where it is used, the result will be the same. Even if you defined the function in bar.cpp, but used it in main.cpp, I think it will be the same, although not entirely sure (you can try). And I'm sure that if you linked bar.cpp and main.cpp with different modules (shared library and executable), then you can wrap the function from bar.cpp used in main.cpp, again, regardless of whether the template is or not .


Update 2: I was not sure, but Mike confirmed the experiment (see his own answer and comments there) that the wrapper works if the character is undefined in the object file, even if this object file is linked with another object file containing the definition of the character. Excellent!

+1
source

The comments were useful, but I don’t think it is necessary to split it into an executable and (shared) library. The key is to have a front declaration for the template function in the origin of the call and create an instance of the template function with the type used in a separate translation unit. This ensures that f is undefined in bar.o:

 //bar.cpp #include "bar.h" template<typename T> void f(T); void bar() { f(42); } //fh template<typename T> void f(T t) { } //f.cpp #include "fh" template void f(int); $ nm bar.o U _Z1fIiEvT_ 0000000000000000 T _Z3barv 
+1
source

Source: https://habr.com/ru/post/906206/


All Articles