Saturday, 10 January 2015

C++ Member Function Variables And Different Abi's

In Gcc, and all C++ compilers they use a structure to store information about member functions. A member function can be virtual or non-virtual. So doing something like...

auto TheFunctionX = &MyClass::Function;

Will yield a variable of a hidden structure type with two fields. These fields are later used to compute the real address of the function in memory. The structure variable might already contain the address if the function is not virtual but knowing that just from the structure requires knowing how the fields in the structure work. Unfortunately the details of how compilers implement this structure varies wildly, but for Gcc at least it is stable in that for a given ABI(Binary Interface), they will not change the details.

Assuming you can rely on the ABI you can then use your own code to interpret the real address of virtual functions and non-virtual member functions, even in interfaces. To do so you need the structure, which you can compute once knowing the type of the class, or just compute it each time you need it, and you also need the instance of the class for which you want the address. The reason you need the instance to get a virtual functions address is because the instance has the vTable. Technically for any given class instance(which is not using multiple inheritance), you can compute the address of any member function and save it.

The point is to understand that because you can compute the address, you can then go on to make other structures of your own to implement something which functions exactly like the events mechanism of Delphi.

This small class here shows an example of such a member function structure as used in the standard Itanium Abi for Gcc. Gcc supports different Abi's so it is not always the same. That requires more understanding of Abi in general between different Abi.

struct TGccMemberFunctionDetails {
   union {
     intptr_t non_virtual_address; // always even, the actual address of a normal non-virtual instance method
     intptr_t virtual_offset; // always odd, the offset into the vtable of the adjusted this pointer
   };
   intptr_t delta;// The this pointer adjustment. Used for interfaces and multiple inheritance cases

   // Given an instance pointer aka "this", compute 2 things.
   // 1. The adjusted this pointer.
   // 2. The real address of the proc
   TComputedPmf Compute(void* cthis) {
      TComputedPmf result;
      result.inst = cthis + delta;
      if (non_virtual_address & 1) result.proc = (void*)(* (intptr_t**)( *(intptr_t**)result.inst + (virtual_offset+1)/2) + sizeof(void*));
      else result.proc = (void*)non_virtual_address;
      return result;
   }
};

The Compute method returns another structure containing the address of the function and the corrected instance pointer(which for normal classes is the same as the input cthis).

Once you have the address and the corrected this you can the save these variables and use them like Delphi events by making a template class to wrap them in. Unfortunately it is not that type safe and you will have to watch your calling conventions but the general idea is to pass the corrected this argument first and then the rest of the parameters after the this. The call will go to a thunk if it was an interface or multiple inheritance method  requiring a thunk in either case.

If you are still reading then this is probably new to you, and you probably want Delphi or C# style events. So all you need to take from this brief introduction is faith in the concept and that it does work and that the execution speed is very fast to cal the function(the same as Delphi).

The problem then is how to make the event. It is very simple... This simple C++11 class here can serve you as a basis for all your events. If you need an event that returns void just define another class but omit the TResult type parameter and return nothing from the Call procedure. You can also overload the call operator to make the code look like its calling a function!

template<class TResult, typename... TArgs>
class TFunctionOfObject {
public:
  typedef TResult (*TProc)(void*, TArgs...);
  TProc proc;
  void* inst;
 TFunctionOfObject () { }
  TFunctionOfObject (const TComputedPmf& pmf) {
    proc = pmf.proc;
    inst = pmf.inst;
  }
  inline __attribute((force_inline))__  TResult Call(TArgs... args) {
    return proc(inst, args...);
  }
};

// Declare an event proc that returns bool and takes one parameter which is an integer
using TMyEvent = TFunctionOfObject<bool,int>;

I leave the rest up to you as to how to derive the TComputedPMF structure that you can pass to the constructor. Or maybe I will edit this some more later.

Hint! I like to use a macro called _PMFX and the decltype variable to compute this on the fly, so I can say...

Font.OnChanged = _PMFX(this, OnFontChanged) ;

Then inside the macro I use the decltype of the this variable to get at the compilers structure for the member function, and then I use the Abi specific structure(like the Gcc example above), to get at the computed PMF and then it just goes into the constructor of the OnChanged field of Font in this example.



Debugging Vst Plugins Using Codeblocks...

Vst plugins are .dll files and so they need a host application to debug. The best application I have seen for doing this with using C++ is Codeblocks as the editor, with an application like Reaper. When you hit a breakpoint, control is transferred back to Codeblocks and Reapers threads and audio goes off while you are single stepping the code.

The steps to do this debugging of Vst and Vsti plugins are...

1) Get your Vst plugin going as a C++ or better C++11 project in Codeblocks.
2) In Codeblocks, there is a top level menu called "Projects". In this menu is an item called "Set Programs Arguments".
3) Go to the programs arguments panel and enter the full path to the Vst host such as  Reaper.exe(Or any other Vst host as well but Reaper works well and is free to try for this purpose).
4) Now build the program and then hit the debug button on the toolbar. The Vst host will run. Load your plugin into the host. In Reaper this means add it as an instrument or effect in the track.
5) Any breakpoints you have set in your Vst source code will now be hit when the plugin runs and you can debug the plugin like normal program debugging and do things like evaluating variables etc...

I do not know if the default compiler with Codeblocks will work well for this, because I downloaded a different newer MingW(Gcc 4.9), and I changed the Gcc path to the new MingW.




GCC C++11 Alternative To Try/Finally

In C++11 and C++ there is no try/finally that you can use. So often you have to make classes to do cleanup for you. But with the new C++11 there are now lambdas and you can use these as bound functions that can be executed later at anytime. In the case of finally we want a lambda that does the cleanup and is executed later on at the end of the scope, just like manual cleanup of some memory or files etc...

/*
  This class defers a single void function call by wrapping it
  in a function and calling it later. Because this is C++11 you
  can pass it a lambda function.
*/
class deferred_function_call {
  std::function<void(void)> the_function;
public:
  inline deferred_function_call(const std::function<void(void)> &the_function) : the_function(the_function) { }
  inline ~deferred_function_call() { the_function(); }
};


#define _DO_TOKEN_COMBINE__(X,Y) X##Y  // helper macro
#define _TOKEN_COMBINE__(X,Y) _DO_TOKEN_COMBINE__(X,Y)

/*
  What name you use to remember something to do at the end of the scope is your choice. I like
  RememberTo
*/
#define _FINALLY(...)    deferred_function_call _TOKEN_COMBINE__(_x_temp__,__LINE__) ([&]{ __VA_ARGS__ ; })
#define REMEMBER_TO(...) deferred_function_call _TOKEN_COMBINE__(_x_temp__,__LINE__) ([&]{ __VA_ARGS__ ; })
#define remember_to(...) deferred_function_call _TOKEN_COMBINE__(_x_temp__,__LINE__) ([&]{ __VA_ARGS__ ; })
#define RememberTo(...) deferred_function_call _TOKEN_COMBINE__(_x_temp__,__LINE__) ([&]{ __VA_ARGS__ ; })
#define defer(...) deferred_function_call _TOKEN_COMBINE__(_x_temp__,__LINE__) ([&]{ __VA_ARGS__ ; })

#define later(...) deferred_function_call _TOKEN_COMBINE__(_x_temp__,__LINE__) ([&]{ __VA_ARGS__ ; })


/*
  This macro is for calling a function pair where the second call must execute.

    For example:
      GuardedExpression(EnterCriticalSection(&MyLock),LeaveCriticalSection(&MyLock))
*/
#define GuardedExpression(expression_start,expression_finally) expression_start; deferred_function_call _TOKEN_COMBINE__(_x_temp__,__LINE__) ([&]{ expression_finally;  })

EXAMPLES


// Here is some example code that shows how to use such a macro to make your code cleanup for you
int main {

/*
  Example function calls that are made in order and must execute
*/
class TCanvas {
public:
  void MoveTo() {}
  void LineTo() {}
  void BeginDrawing() {}
  void EndDrawing() {}
  void MoveTo(int x, int y) {}
  void LineTo(int x, int y) {}
};
void BeginDrawing(TCanvas* canvas) {
  // Do stuff that happens before drawing, for example.
}
void EndDrawing(TCanvas* canvas) {
  // Do stuff that happens after drawing, for example.
}

int main()
{
  {
    FILE *file = fopen("test_Cxx11_Finally","w");
    remember_to( fclose(file); );
    printf("Do stuff with the file...\n");

    // read something
    // write something

    printf("All went well, now the file will be closed by the remember_to...\n");
  }
  {
    /* This example assumes the existence of some TCanvas object. */
    TCanvas MyCanvas;
    BeginDrawing(&MyCanvas);
    RememberTo(EndDrawing(&MyCanvas));

    printf("Drawing some stuff!\n");
    MyCanvas.MoveTo(0,0);
    MyCanvas.LineTo(100,100);
  }
  {
    /* Or you can make it call the class methods. remember_to will take any code even a block of code... */
    TCanvas MyCanvas;
    MyCanvas.BeginDrawing();
    RememberTo(MyCanvas.EndDrawing());
    printf("Drawing some stuff!\n");
    MyCanvas.MoveTo(0,0);
    MyCanvas.LineTo(100,100);
  }
  {
    /* You could guard a new/delete sequence */
    TCanvas* MyCanvas = new TCanvas;
    RememberTo( delete MyCanvas );
    printf("Executing in a guarded section!\n");
    MyCanvas->MoveTo(0,0);
    MyCanvas->LineTo(100,100);
  }
  {
    /* Or like this */
    GuardedExpression(TCanvas* MyCanvas = new TCanvas, delete MyCanvas);
    printf("Drawing inside a guarded section!\n");
    MyCanvas->MoveTo(0,0);
    MyCanvas->LineTo(100,100);
  }
  {
    /*
      This naive example shows that you can use a block of code as
      well in the remember_to clause.
    */
    int MyCounter = 0;
    RememberTo({
       // Do stuff here like a normal block, this will be executed
       // at the end of the enclosing scope.
       if (MyCounter != 10)
         printf("The code did not execute all the loop!\n");
    });
    // Here it tries to loop and the remember clause will detect if the
    // loop did every iteration it was supposed to.
    while (MyCounter < 10) {
      if (MyCounter == (rand() % 30))
        throw "Something happened!";
      MyCounter++;
    }
    printf("Everything went fine!\n");
  }

}