the Compartmented Robust Posix C++ Unit Test system

CRPCUT_WRAP_V_FUNC(lib, func, rv, param_list, param_call)

Define a wrapper around a global function

Used in: User defined namespace scope

Define access to a library function you want to write a wrapper for, for example for checking parameters or inject hard-to-test error situations.

[Note]Note
CRPCUT_WRAP_V_FUNC uses dlopen() and dlsym() to get access to the library function. This means you can only access functions in a shared library, and also that functions used by dlopen() and dlsym() are very tricky to get access to. crpcut already provides wrappers for the heap (See crpcut::heap.)

[Caution]Caution
Do not expand CRPCUT_WRAP_V_FUNC in global scope, or you will be unable to make a wrapper, since the expansion will create a new function with the same name.

Macro parameters

lib

The library with the function. crpcut predefines libc and librt.

To write a wrapper for a function defined in another library, a name access function in namespace crpcut::libs must be provided.

func

The name of the function, without quotes.

rv

The return type of the function, which obviously is void, but can also add attributes like the GCC extension __attribute__ ((noreturn))

param_list

The types and names for all parameters to the function, enclosed in parenthesis.

param_call

The names from param_list without type information, comma separated and enclosed in parenthesis.

Example: The test program

     
     #include <crpcut.hpp>
     
     extern "C"
     {
     #include <stdio.h>
     #include <string.h>
     }
     
     namespace original {
       CRPCUT_WRAP_V_FUNC(libc,
                          exit,
                          __attribute__ ((noreturn)) void,
                          (int code),
                          (code))
     }
     
     int expected_code = 0;
     extern "C"
     {
       __attribute__ ((noreturn)) void exit(int code) throw ()
       {
         if (expected_code != code)
           {
             FAIL << "exit() called with " << code <<
               " when " << expected_code << " was expected";
           }
         original::exit(code);
       }
     }
     
     TEST(wrapped_exit_succeeds, EXPECT_EXIT(ANY_CODE))
     {
       expected_code = 3;
       exit(3);
     }
     
     TEST(wrapped_exit_fails, EXPECT_EXIT(ANY_CODE))
     {
       expected_code = 3;
       exit(0);
     }
     
     int main(int argc, char *argv[])
     {
       return crpcut::run(argc, argv);
     }

        

reports one failed test:


     FAILED!: wrapped_exit_fails
     phase="running"  --------------------------------------------------------------
     samples/wrap_v_func.cpp:51
     exit() called with 0 when 3 was expected
     -------------------------------------------------------------------------------
     ===============================================================================
     2 test cases selected
     
                    Sum   Critical   Non-critical
     PASSED   :       1          1              0
     FAILED   :       1          1              0

        

See crpcut::libs for details.

See also CRPCUT_WRAP_FUNC(lib, func, rv, param_list, param_call) for functions returning a value, EXPECT_EXIT(num, action?), ANY_CODE and FAIL