Plugin-Schnittstelle

| ALPHA-VISION® SoftPlc7

# Plugin-Schnittstelle

## 1. Allgemeines

Die Plugin-Schnittstelle bietet dem Programmierer die Möglichkeit, während des Programmablaufs in einem vorgeschriebenen Takt selbst geschriebene Funktionen ausführen zu lassen. Dieser Takt wird bestimmt durch die SoftPlc7.ini-Einstellung [Startup] TimeSliceMilliSec=<Millisekunden> und koordiniert die verschiedenen OB-Zyklen.
Eine Plugin-Funktion besitzt immer folgende Signatur:

extern "C" __declspec(dllexport) void _cdecl <Funktionsname>(HANDLE* phEvent);

Innerhalb dieser Funktion muss beim ersten Aufruf ein Objekt der Klasse PluginHandler instanziiert werden, dabei werden unter anderem zwei Funktionszeiger im Konstruktor übergeben, bei jedem weiteren Aufruf wird die einfach die Start-Funktion des PluginHandlers aufgerufen. Die erste übergebene Funktion wird dann immer am Anfang einer Zeitscheibe ausgeführt, die zweite Funktion am Ende. Ein NULL-Zeiger anstatt eines Funktionszeigers bedeutet, dass keine Funktion aufgerufen werden soll.

## 2. Beispiel

Folgendes Beispiel zeigt, wie eine Plugin-Funktion in einer eigenen DLL implementiert werden kann, sie befindet sich auch im Beispiel-Projekt 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;
    	}
    }