Plugin-Interface

SUMMARY

Description of the Plugin-Interface.

CONTENTS

  1. Introduction
  2. Example

Introduction

The Plugin-Interface offers the opportunity to execute a defined function on a defined cycle when a program is running. The Cycle is defined by a section entry in the SoftPLC7.ini file:

Startup
TimeSliceMilliSec=<Function Name>

Syntax for a Plugin-Function:

Extern “C”__declspec(dllexport) void_cdecl <Function Name>(HANDLE*phEvent);
	             

Within that function on the first call an object of the class PluginHandler must be be instantiated. Thereby 2 Function-Pointers are handed over in the constructor; any additional call invokes the Start-Function of the Plugin-Handler. The function handed over first is executed on start of a time slice the second one on the end. A ZERO-Pointer instead of a Function-Pointer indicates that no function is called.

Example

The following example shows how a Plugin-Function is implemented in a DLL, it also shown in the example project “SoftPLC7SampleHll”.



// --------------------------------------------------------------------------
// --- Here's an example that demonstrates how to define a plugin function.
// --------------------------------------------------------------------------

#define SOFTPLC7_SAMPLEHLL_API __declspec(dllexport)

// helper function: print some bytes of M-area
void DebugOutMerkerBytes(CString strPre)
{
        HllHandler        oHandler;
        BYTE        pbBuf[10];
        WORD        wRead = oHandler.GetBytes(TYPE_M, 0, pbBuf, 10);
        CString        strOut;
        if (wRead != 10)
        {
                strOut.Format(_T("HllHandler::GetBytes failed, only got %d 
				Bytes."), (long) wRead);
        }
        else
        {
                for (long lAct=0; lAct < 10; lAct++)
                {
                        CString        strByte;
                        strByte.Format(_T("%02x "), (long) pbBuf[lAct]);
                        strOut += strByte;
                }
        }
        TRACE0(strPre + strOut + _T('\n'));
}

// This is the function that's executed before any OB is executed.
void MyFirstFunction()
{
        HllHandler        oHandler;
        if (oHandler.CPUIsRunning())// do nothing in STOP mode
        {
                DebugOutMerkerBytes(_T("before execution: "));
        }
}

// This is the function that's executed after all OBs have been executed.
void MySecondFunction()
{
        HllHandler        oHandler;
        if (oHandler.CPUIsRunning())// do nothing in STOP mode
        {
                DebugOutMerkerBytes(_T("after  execution: "));
        }
}

// We need a PluginHandler object.
static PluginHandler*        s_pHandler = NULL;

// This is the "plugin function".
SOFTPLC7_SAMPLEHLL_API void _cdecl SampleFunctionPlugin(HANDLE* phEvent)
{
        if (s_pHandler == NULL)
        {
                TRACE0(_T("Initializing Plugin: SampleFunctionPlugin\n"));
                // Let's create a PluginHandler, give him the 2 events and 2 
				functions.
                s_pHandler = new PluginHandler(phEvent[0], phEvent[1], 
				MyFirstFunction, MySecondFunction);
        }
        else
        {
                // Set start event, MyFirstFunction will be executed soon.
                s_pHandler->Start();
        }
}

// Any exported function "void (*ExitSoftPlc7Dll)()" in a linked DLL such as 
this DLL
// is executed before the program terminates.
extern "C" SOFTPLC7_SAMPLEHLL_API void ExitSoftPlc7Dll()
{
        TRACE0(_T("Calling ExitSoftPlc7Dll@SoftPlc7SampleHll.dll"));
        static bool        bFirst = true;
        if (bFirst)
        {
                bFirst = false;
                delete s_pHandler;
                s_pHandler = NULL;
        }
}