Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 08:06, 13 September 2007.

Communication options between Open C engine and S60 UI

From Forum Nokia Wiki

Contents

Introduction

This article examines the different ways to combine Open C functionalities to a S60 application. Depending on the amount of functionality and type of data one can choose to either include the Open C code directly to a S60 application binary or to create a new binary. The Open C binary can be a separate executable which runs in a separate process or a library that is used by the S60 application executable.

Open C functionality in a separate process

Depending on the type of functionality that the Open C component provides there are several ways to design the communication (IPC) between the processes.

// Constants used in the examples
 
_LIT(KNoName, "");
_LIT(KTxtPanic,"Panic");
_LIT(KEngineName, “MyEngine.exe”);
 
#define KQueueIndex 	10
#define KChunkIndex 	11
#define KMutexIndex	12
#define KMemSize	1024

1) Launch engine process and wait until it finishes

/**
 * S60 UI application
 */
void CMyClass.CallEngineL(const TDesC &aCommandLine)
    {
    TRequestStatus status;
    RProcess process;
 
    User::LeaveIfError(process.Create(KEngineName, aCommandLine));
    process.Logon(status);
    process.Resume();
 
    User::WaitForRequest(status); // wait until the engine process finishes
    process.Close();
    }
/**
 * Open C engine
 */
int main(int argc, char* argv[])
    {
    // ENGINE CODE
    }

2) Exchange information between two running processes

If there exists a continuous flow of data between the processes a channel needs to be created. To handle the communication channel a layer of Symbian code is added on top of the Open C engine code. The main() function is replaced by E32Main() function.

/**
 * New entry point for engine
 */
LOCAL_C void OpenCMainL(TPtrC &aCommandLine)
    {
    // ENGINE CODE 
    }
/**
 * A normal Symbian OS executable provides an E32Main() function which is
 * called by the operating system to start the program.
 */
GLDEF_C TInt E32Main()
    {
    CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
	
    // run actual engine code
    RProcess process;
    TRAPD(error,OpenCMainL(process.CommandLine())); 
 
    __ASSERT_ALWAYS(!error,User::Panic(KTxtPanic, error));
 
    delete cleanup; 	                       // destroy clean-up stack
    return 0; 						    
    }

2.1) Using message queue

S60 U application code

// Data members 
	RProcess iProcess;	
	RMsgQueue<TInt32> iQueue;
// Initialization
	User::LeaveIfError(iQueue.CreateGlobal(KNoName, 1);
	User::LeaveIfError(iProcess.Create(KEngineName, aCommandLine));
 
	iProcess.SetParameter(KQueueIndex, iQueue);
	iProcess.Resume();
// Engine update
	TInt32 msg;
	iQueue.ReceiveBlocking(msg);
// Finalization
	iProcess.Kill(KErrNone);
	iQueue.Close();
	iProcess.Close();

Open C engine code

#include <e32std.h>
#include <e32base.h>
#include <e32cons.h>
#include <e32msgqueue.h> 
 
LOCAL_C void OpenCMainL(TPtrC &aCommandLine)
   {
   RMsgQueue<TInt32> queue;
   User::LeaveIfError(queue.Open(KQueueIndex)); 
 
    while ( ... )
        {
        ...
        // Update UI process
        TInt32 msg;
        queue.SendBlocking(msg);		
        }
    queue.Close();
    }

2.2) Using global memory

S60 UI application code

// Data members 
    RProcess iProcess;
    RChunk iChunk;
    RMutex iMutex;
// Initialization
    User::LeaveIfError(iChunk.CreateGlobal(KNoName, KMemSize, KMemSize));
    User::LeaveIfError(iMutex.CreateGlobal(KNoName));
    User::LeaveIfError(iProcess.Create(KEngineName, aCommandLine));
 
    iProcess.SetParameter(KChunkIndex, iChunk);
    iProcess.SetParameter(KMutexIndex, iMutex);
 
    iProcess.Resume();
// Engine update
    iMutex.Wait();
    unsigned char* ptr = iChunk.Base(); // Get global memory base address
    ...
    iMutex.Signal();
// Finalization
    iProcess.Kill(KErrNone);
    iMutex.Close();
    iChunk.Close();
    iProcess.Close();

Open C engine code

#include <e32std.h>
#include <e32base.h>
#include <e32cons.h>
 
LOCAL_C void OpenCMainL(TPtrC &aCommandLine)
    {
    RChunk chunk;
    RMutex mutex;
 
    User::LeaveIfError(chunk.Open(KChunkIndex)); 
    User::LeaveIfError(mutex.Open(KMutexIndex)); 
 
    while ( ... )
        {
        ...
        // Update UI process
        mutex.Wait();
        unsigned char* ptr = chunk.Base(); // Get global memory base address
	...
        mutex.Signal();
        }
    chunk.Close();
    mutex.Close();
    }


Open C functionality in a library

Open C functionality within the application binary

 
Powered by MediaWiki