How to call a function with function pointers in a C/C++ DLL with TestStand

Updated Oct 28, 2024

Environment

Software

  • TestStand

Programming Language

  • C
  • C++

I want to use "callback functions" in C/C++ DLL, so I want to set "function pointers" as arguments of C/C++ DLL adaptors in TestStand.
Could you show me the way how TestStand C/C++ DLL adaptor work with such function pointers as arguments?
 

Here in this article, we demonstrate 2 methods of achieving this.

  1. Wrapper Function
  2. Store the function pointer in TestStand

The first method is to create a wrapper function in C/C++ so that they can call the new-built 'wrapper function' instead of directly call the "original function in the DLL with function pointer parameter".

The diagram below simply illustrates the relationships among the (1) TestStand seq, (2) the newly built wrapper function, (3) the target DLL file:

callbackfunction

In short, the step in TS is calling a wrapper function instead of directly calling the function in the targeted DLL; besides, there are at least 1 function along with the wrapper function in the same dll to be passed as the callback function when calling the function in the targeted dll.

 

The second method leverages the TestStand primitive variable type - Object Reference. Use the object reference to store the reference to a function, then pass it as an argument to the target function for callback.
  1. In the C/C++ DLL, it should include
    1. the callback functions
    2. a function to return these callback functions (for variables in TS to store them for later use)
    3. the target function that takes callback function as an input parameter
  2. In the TS seq, there are:
    1. variables (object reference type) to stores the callback functions, and a step to get the callback functions from the DLL
    2. call the target function

 

Below are example snippets of the second method of the TestStand sequence and code snippet in the DLL:

1. The step to retrieve the reference to the callback function (pointer points to a function):
ts_getfunc.JPG

2. The step to call the target function with callback:
ts_callback_step.JPG

3. The code snippet in the source code of the DLL:
#include <limits.h>
#include "MathLibrary.h"

// My add function.
void add_numbers(int a, int b, int* sum) {
    *sum = a + b;
}

// My minus function.
void minus_numbers(int a, int b, int* difference) {
    *difference = a - b;
}

void* get_function(const int selection) {
    void (*add_func_ptr)(int, int, int*);
    add_func_ptr = &add_numbers;
    void (*minus_func_ptr)(int, int, int*);
    minus_func_ptr = &minus_numbers;

    if (selection == 1)
        return add_func_ptr;
    else
        return minus_func_ptr;
}
typedef void (*FunctionPtr)(int, int, int*);

// My target function.
void targeted_func(FunctionPtr callback, int a, int b, int* result) {
    (callback)(a,b,result);
}
 

Next Steps

The only difference between these 2 methods is that WHERE do we decide WHICH function to be as the callback function

  • In wrapper function method: we use an additional wrapper function which takes an additional input as the selection of the callback function to be passed to the target function
  • In TestStand storing the callback function: we create an object reference (to store funciton pointer) in TS, and add some if-else, or switch, or any other logic to the sequence, and pass the function pointer to the target function in the targeted DLL