Click here to Skip to main content
15,884,472 members
Articles / Desktop Programming / MFC

COOP - Co-operate Library to Transfer Data between Processes

Rate me:
Please Sign up or sign in to vote.
4.40/5 (10 votes)
28 Feb 2010CPOL3 min read 25.3K   964   41   4
Co-operate library to start another process and transfer data between processes

Introduction

Co-operate library can be used to start another process, and then it provides a way to transfer data between processes.

Background

Co-operate library is to let 2 programs co-operate with each other. One program can start the other program, and then any one of them can transfer data to the other, and then one can detect whether the other program has exited.

I write this library because I want to allow my 2 programs to co-operate, like Photoshop and ImageReady do, that one image can be passed from Photoshop to Imageready to be edited continuously.

This library is also useful if you want to let your program co-operate with someone else's program.

Using the Code

This co-operate library provides a set of stdcall APIs, to start process, to send data, to detect whether the other program exited, to set a callback function which will be called when data arrives from the other program.

There are no classes or complex types defined in the header file. This library can be used not only by Visual C++, but also by Visual Basic, Delphi, etc.

Interface Reference - coopframe.h

Type Definition

C++
// 
// Use this handle to stand for session between processes
// 
DECLARE_HANDLE(HCOOPSESSION);
 
//
// Callback function definition, which will be called when data arrives
//
typedef VOID (CALLBACK* COOPPROC)(LPCVOID pData, UINT nSize, LPVOID pParam); 

API

C++
//
// If current process is created by co-operator, the return value is not NULL
//
HCOOPSESSION STDCALL GetCoopSession(COOPPROC fnCoopProc, LPVOID pParam);
 
//
// Create a process
//
HCOOPSESSION STDCALL StartCoopSession
	(COOPPROC fnCoopProc, LPVOID pParam, LPCTSTR szPath, LPCVOID pData, UINT nSize);
 
//
// Set callback function
//
VOID STDCALL SetCoopSessionProc
	(HCOOPSESSION hCoopSession, COOPPROC fnCoopProc, LPVOID pParam);
 
//
// Is co-operator still running
//
BOOL STDCALL IsCoopSessionValid(HCOOPSESSION hCoopSession);
 
//
// Release session
//
VOID STDCALL CloseCoopSession(HCOOPSESSION hCoopSession);
 
//
// Send data to co-operator
//
VOID STDCALL SendToCoopSession(HCOOPSESSION hCoopSession, LPCVOID pData, UINT nSize);

Steps of Co-operate

Step 1: Detect whether this program is started by co-operator

C++
// Required : test if started by co-op program
m_hCoopSession = GetCoopSession(CoopCallbackProc, param);

The return value of GetCoopSession() is not NULL if this program is started by another program with StartCoopSession(). This step is necessary if this program is started by co-operator, or the call of StartCoopSession() will be blocked for a long time.

The first argument is a callback function, and the second is a parameter, which will be passed back to the callback function when callback is called.

The callback, CoopCallbackProc() will be called the first time before GetCoopSession() returns, with the data which is passed into StartCoopSession() in the other program.

Step 2: Start the other program if there is no session with co-operator

C++
if(!IsCoopSessionValid(m_hCoopSession))
{
    // release the previous session
    CloseCoopSession(m_hCoopSession);
 
    m_hCoopSession = StartCoopSession
	(CoopCallbackProc, param, "other_program.exe", pData, length_of_data);
}

If the session is NULL or if the other program has exited, the IsCoopSessionValid() will return FALSE. Then, use StartCoopSession() to start the other program and it will return the handle of session.

The data will be transferred to the newly started program's callback function, which is passed into GetCoopSession() in the started program.

Step 3: Pass data to the other program if the session is still valid

C++
if(IsCoopSessionValid(m_hCoopSession))
{
    // co-op program is still running
    SendToCoopSession(m_hCoopSession, pData, length_of_data);
}

The data will be passed to the callback function of the other program.

Step 4: Process data's arrival

C++
VOID CALLBACK CoopCallbackProc(LPCVOID pData, UINT nSize, LPVOID param)
{
    // pData - is a pointer to data, this data comes from the other program
    // nSize - comes from the other program
    // param - this value is set along with the callback by 'GetCoopSession()' 
    //         or 'StartupCoopSession()'
    //         or 'SetCoopSessionProc()'
}

When data arrives from the other program, this callback function will be called.

Step 5: Close session handle when program exits or stops to co-operate

C++
CloseCoopSession(m_hCoopSession);
m_hCoopSession = NULL;

Technical Points

  • I used CreateProcess() to create a new process.
  • I used CreateFileMapping() to share memory between processes.
  • I used DuplicateHandle() to pass process handle and event handle from one process to the other.
  • I used GetProcessTimes() to determine whether the other process has exited.
  • I used a thread to monitor event of data arrival.

Explanation of Visual Basic's Multi-Thread

When I was writing the demo program for Visual Basic, I encountered a problem that I could not do anything about in callback function, such as MsgBox or CopyMemory to an array. I tried to find out the problem for days, and finally I found that Multi-Thread caused the problem.

I create a new thread in 'Visual C++' to monitor event of data arrival, but this thread has no necessary context for 'current Visual Basic program', so within the callback function, we cannot use anything in Visual Basic.

There is a complex mechanism to build context for a new thread in Visual Basic, so I chose to use SendMessage() to send the address to the main window to get the content of data.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
China China
Begin coding from basic, since 1994. Interested in coding and database and website constructing.
My website: http://www.regexlab.com/ - Regular Expression Laboratory
The easiest regex engine: http://www.regexlab.com/deelx/

Comments and Discussions

 
GeneralMy vote of 1 Pin
Jim Crafton8-Mar-10 6:09
Jim Crafton8-Mar-10 6:09 
GeneralRe: My vote of 1 Pin
sswater shi8-Mar-10 7:26
sswater shi8-Mar-10 7:26 
Generalgood work Pin
karim ben romdhane8-Mar-10 0:07
karim ben romdhane8-Mar-10 0:07 
good work continueThumbs Up | :thumbsup:
As I grow up I pay less attention to what men say, I just watch what they do.

GeneralRe: good work Pin
sswater shi8-Mar-10 7:03
sswater shi8-Mar-10 7:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.