Creating the SBM Library Object

SBM ModScript can load a DLL and call any function within the DLL as long as the function has the following interface:

extern "C"__declspec( dllexport ) int function_name( SBMScriptArg*, int, ReallocArg_t );

where the first argument is an array of SBMScriptArg objects, the second parameter is the number of objects in the array, and the third is a callback function pointer back into SBM to resize any of single SBMScriptArg in the array. The extern "C" portion prevents function name mangling, which enables SBM to find this function in the DLL. The declspec portion defines your function as a dll export.

When building your libraries, you must include a header file with the following definition:

struct SBMScriptArg
  {
    char* pData;
    int   size;
  };
typedef int (*ReallocArg_t)( SBMScriptArg* pArg, int newSize );

It does not matter what you name the function as long as it has the correct interface. Each SBMScriptArg is both input and output for the DLL. To change the value of the SBMScriptArg, the ReallocArg function can be used to ensure that the buffer size is big enough for your output. All input and output are strings; integers can be converted to text using functions like std::to_string( n ).

Tip: When creating your DLL, remember to export the functions by listing them in your .def file as well as declaring them for export with __declspec(dllexport).

Example:

// the following setArg functions can be used to set an SBMScriptArg to a new value
void setArg( const char* s, size_t len, SBMScriptArg& arg, ReallocArg_t reallocArg )
{
  assert( len < INT_MAX );
  // reallocArg will check if size is already big enough
  reallocArg( &arg, static_cast<int>( len + 1 ) );
  memcpy( arg.pData, s, len );
  arg.pData[len] = 0;
}

inline void setArg( const char* s, SBMScriptArg& arg, ReallocArg_t r )
{
  setArg( s, s ? strlen( s ) : 0, arg, r );
}

inline void setArg( const std::string& s, SBMScriptArg& arg, ReallocArg_t r )
{
  setArg( s.c_str(), s.size(), arg, r );
}

template <typename T>
inline void setArgT(  T n, SBMScriptArg& arg,ReallocArg_t r )
{
  setArg( std::to_string( n ), arg, r );
}