Extending Stingray Libraries
Stingray classes extend Microsoft Foundation Class (MFC) classes. You, in turn, can create classes that build on and extend the Stingray classes. To create these extensions, you need to understand the mechanism for importing and exporting symbols. This section first describes how Stingray itself does this, and then describes what you must do when creating Stingray extensions.
How Stingray Imports and Exports Symbols
In an extension library, symbols (functions and variables) must be exported so they have visibility to an application that is linking to the library. When an application links to an extended library, it imports the functions for use. Previously in Stingray Studio products there was no need to mark functions and variables for exportation, but this is now a requirement. Definition files (.def) are no longer used by the Stingray libraries to export functions and variables. Instead the C++ __declspec keyword is used to export and import functions and variables.
*__declspec(dllexport) is used by the library to export.
*__declspec(dllimport) is used by the application to import.
The Stingray libraries use a header file that defines common macros for exporting and importing functions and variables. Each product contains a header file called <product_name>ExportDefs.h that is located in the <stingray-installdir>\Include\<product_name> directory. During installation, a master header file called StingrayExportDefs.h is updated to #include each purchased and selected product's *ExportDefs.h header file to the master header file. The master header file is located in the <stingray-installdir>\Include directory.
The Stingray product implementation files define one of the following preprocessor symbols to indicate in our code that we are going to export symbols:
Versions of Stingray Studio older than Stingray Studio 2006 v3 have the following implementation preprocessor commands defined for backward compatibility:
The Stingray libraries use preprocessor definitions to indicate a function’s or variable’s export/import status. StingrayExportDefs.h defines whether a function or variable is exported or imported by defining one of the following:
NOTE >> The above <product>_API macros should not be used in an extension library as they will cause symbol conflicts with exporting and importing. See the section below on using CustExtDefs.h to create extension libraries.
For example, the Foundation preprocessor is defined as:
#ifdef _SFLDLL // Dynamic Link Library
#define FOUNDATION_API __declspec( dllexport )
extern "C" rettype __declspec(dllexport)
#define FOUNDATION_API __declspec( dllimport )
// Reference to a GLOBAL Function
extern "C" rettype __declspec(dllimport)
#else // !_SFLDLL // Static Link Library
// Reference to a GLOBAL Function: these must be inline
// definitions with no function prototype.
extern "C" rettype __cdecl // Don't mangle the name.
// Must use __cdecl here.
A Stingray class might look like the following:
// StingrayClass.h
#pragma once
#include “StingrayExportDefs.h”
class CFoundationFoo
FOUNDATION_API CFoundationFoo();
FOUNDATION_API virtual ~CFoundationFoo();
FOUNDATION_API virtual void Add(int iVal);
// Note private variables don’t need to be exported.
int m_Sum;
FOUNDATION_GLOBAL_FUNC_API(void) DoSomethingGlobal();
// StingrayClass.cpp
#include “StingrayClass.h”
m_Sum = 0;
Void CFoundationFoo::Add(int iVal)
m_Sum += iVal;
FOUNDATION_GLOBAL_FUNC_API(void) DoSomethingGlobal()
// Do something.
When the above class is compiled, it will export the functions in the class because __declspec(dllexport) will be defined internal to the Stingray library that the class extends.
When a sample or application uses the CFoundationFoo class, it only needs to include its header file. Because _SFL_EXPORT_IMPL is not defined in the sample or application, the functions and variables will be imported for use because __declspec(dllimport) will be defined.
Using CustExtDefs.h in Stingray Extensions
Stingray extension libraries can be created as static libraries (lib) or dynamic link libraries (dll). Extension libraries are then linked to an application. An extension library needs to expose its functionality to the application by exporting its functions and variables so the application can import them for use.
Like the Stingray libraries themselves, there needs to be some code mechanism to switch between exporting and importing. The *_API macros that are defined for the Stingray libraries should not be used in a Stingray Extension library as they are meant for internal use by the Stingray libraries only.
To make it easier to create Stingray extension libraries, Stingray Studio provides the file CustExtDefs.h in the <stingray-installdir>\Include directory. Including CustExtDefs.h and using its predefined *_API preprocessors will remove the need to create a mechanism in code for switching between importing and exporting.
NOTE >> CustExtDefs.h provides some overrides of the basic MFC macros. For example, the override for DECLARE_MESSAGE_MAP() is CUSTEXT_DECLARE_MESSAGEMAP(). If there are macros that are needed but not provided by the header file, they need to be overridden in the extension library.
If the extension library is to be configured as a dynamic link library (dll), then the preprocessor settings in the library should include _CUSTEXTDLL so the appropriate export/import syntax is used. Static (lib) build configurations should not include this preprocessor symbol.
An extended Stingray class might look like the following:
// ExtendedClass.h
#pragma once
#include “CustExtDefs.h”
#include “StingrayClass.h”
CUSTEXT_GLOBAL_VAR_API static int x; \
{ \
x = 4;
} \
class CSuperFoo: public CFoundationFoo
CUSTEXT_CLASS_FUNC_API inline virtual CSuperFoo(){}
CUSTEXT_CLASS_FUNC_API void DoSomethingSuper();
// ExtendedClass.cpp
#include “ExtendedClass.h”
// Extension/Wrapper of the CFoundationFoo class.
// Call Foo from the base Stingray class.
Extending Stingray Classes Locally in an Executable
Classes in a Stingray library can be extended in an executable locally, meaning that there is no further need to expose functionality outside of the executable. Classes that are extended locally in an executable do not need to use CustExtDefs.h or StingrayExportDefs.h.
The macros listed below are exceptions to the above rule. They need to use the overrides in StingrayExportDefs.h even in a locally extended executable.
An extension class can be derived from a Stingray class without having to export/import symbols. In this case standard MFC macros can be used, such as DECLARE_MESSAGE_MAP(), without any export/import customization. Here is an example:
// MyExtensionClass.h
#pragma once
// Includes ...
class MyExtendedFoo : public CFoundationFoo
// DECLARE_DYNAMIC(MyExtendedFoo) etc.
// Constructor
MyExtendedFoo() {}
// MyExtensionApp.cpp
int main()
// Using the extension class
MyExtendedFoo mf;
return 0;
Combined Visual Studio and Stingray Studio Command Prompt Environment Tool
Stingray provides a command-line tool vc.bat that extends Microsoft’s vcvars.bat to support multiple, separate development environments. This tool allows side by side execution of multiple, supported MSVS compilers with various Stingray Studio solutions and project files, including the past three Stingray Studio versions.
Located in the <stingray_installdir>\Src directory, the command-line usage for vc.bat is:
vc <compiler_ver> <StingrayStudio_ver>
Optional parameters include 64 for 64-bit build environments and mak to just set the environment variables without launching Visual Studio.
From a Command Prompt window, change directory to <stingray_installdir>\Src, and run vc.bat with the relevant parameters:
Compiler version
*15, for VC15 (Visual Studio 2017)*
*14, for VC14 (Visual Studio 2015)
*12 for VC12 (Visual Studio 2013)
*11 for VC11 (Visual Studio 2012)
Stingray Studio version:
*SS12.2 for Stingray Studio 12.2
*SS12.1 for Stingray Studio 12.1
*SS12.0 for Stingray Studio 12.0
*SS11.3 for Stingray Studio 11.3
Platform (optional)
*Use 64 for x64; leave blank for x86
nmake (optional)
*Use mak to set up your environment to run nmake from the correct location. See also “Building from the Command Line with nmake”.
* Note that for Visual Studio 2017, vc.bat must be run from a “Developer Command Prompt for VS 2017”.
VC 11 SS11.3 64
Sets environment for VC11, SS11.3, x64 and launches Visual Studio 2012
VC 11 SS11.3 mak
Sets environment for VC11, SS11.3, x86 for command-line builds with nmake
VC 12 SS11.3
Sets environment for VC12, SS11.3, x86 and launches Visual Studio 2013
VC 12 SS11.3 64 mak
Sets environment for VC12, SS11.3, x64 for command-line builds with nmake
VC 14 SS12.0
Sets environment for VC14, SS12.0, x86 and launches Visual Studio 2015
VC 14 SS12.0 64 mak
Sets environment for VC14, SS12.0, x64 for command-line builds with nmake