Search code examples
c++windowspluginsmacrosfilemaker

What are these C++ Macros doing?


I'm new to C++ and trying to understand what these two macros are doing in this FileMaker Plugin Example.

#define FMX_PROC(retType)           retType __stdcall
#define FMX_PROCPTR(retType, name)  typedef retType (__stdcall *name)

So far I understand that they are both macros, and that the FMX_PROCPTR is a pointer to a function that takes those two arguments, and that __stdcall is some sort of calling convention (decided to not dig to much into what that means).

What I don't understand are the ends of each lines, the parts that come after FMX_PROC(retType) and FMX_PROCPT(retType, name).

It's possible that it is the spacing that is confusing me, but is retType __stdcall the return type for FMX_PROC(retType) ? Or is it giving the argument a type?

Somewhere else in the code FMX_PROC(retType) is used like this

static FMX_PROC(fmx::errcode) Do_FMmp_ConvertToBase( short /* funcId */, const fmx::ExprEnv& /* environment */, const fmx::DataVect& dataVect, fmx::Data& results )

Solution

  • These macros are just to provide the calling-convention __stdcall into the function being defined, or a function pointer alias.

    __stdcall is a non-standard compiler-intrinsic that ensures that functions documented with this attribute will be called with the stdcall calling-convention. This applies to the function itself.

    So the macros respectively:

    • FMX_PROC expands into retType __stdcall, which provides __stdcall to the function. E.g.

      FMX_PROC(fmx::errcode) Do_FMmp_ConvertToBase(...)
      

      expands into:

      fmx::errcode __stdcall Do_FMmp_ConvertToBase(...)
      
    • FMX_PROCPTR expands into a typedef of a function pointer, that is also documented with __stdcall. This is necessary because function pointers don't normally carry calling conventions -- so the compiler doesn't implicitly know when a function expects a different calling convention. To bind a function marked __stdcall to a function pointer, the function pointer itself must carry this information (which is why this alias is needed). This expands into part of the function typedef:

      FMX_PROCPTR(fmx::errcode,Do_FMmp_ConvertToBase)(...);
      

      will expand into

      typedef fmx::errcode(__stdcall *Do_FMmp_ConvertToBase)(...);