The Moth - IPC with CF on CE part 2 (original) (raw)

« IPC with CF on CE part 1 | IPC with Remoting in .NET 2.0 »

Sun, September 12, 2004, 05:16 PM under MobileAndEmbedded

Continuing from previous entry on IPC options with Compact Framework there are only two left - they are very similar.

7. Named Events + registry
8. Directly Share memory

7. For simple data sharing, it is easy for an app to write data to predefined regisrty entries and signal a named event; at that point the other side can read from the registry. It looks something like this:

// SERVER PROCESS

//write data

private void cmdWrite_Click(object sender, System.EventArgs e) {

IntPtr hWnd = Win32Api.CreateEvent(IntPtr.Zero, true,

                                   false, "YOUR_NAME_HERE");


// TODO write to reg

//e.g. with opennetcf Registry class


Win32Api.SetEvent(hWnd);

System.Threading.Thread.Sleep(500);

Win32Api.CloseHandle(hWnd);

}

// CLIENT PROCESS

private System.Threading.Thread mMonitorThread;

private bool mStayAlive;

private IntPtr mMonitorHwnd;

//read data

private void cmdRead_Click(object sender, System.EventArgs e) {

mStayAlive = true;


mMonitorHwnd = Win32Api.CreateEvent(IntPtr.Zero, true, 

                                   false, "YOUR_NAME_HERE");


mMonitorThread = new System.Threading.Thread(

        new System.Threading.ThreadStart(

                            this.MonitorOtherProc));


mMonitorThread.Start();

}

// on background thread so make sure we don't

// touch GUI controls from here

private void MonitorOtherProc(){

while (mStayAlive){

    Win32Api.WaitForSingleObject(mMonitorHwnd, -1);

    if (mStayAlive == false) return;


    MessageBox.Show("Got data "+

            DateTime.Now.ToString(), "TODO read from reg");

    // TODO read data from reg                                 

            
    Win32Api.ResetEvent(mMonitorHwnd);

}

}

// must call this before closing app - e.g. from Form_Closing

public void Shutdown(){

if (mMonitorThread == null) return;

mStayAlive = false;

Win32Api.SetEvent( mMonitorHwnd);		

System.Threading.Thread.Sleep(500);

Win32Api.CloseHandle( mMonitorHwnd);	

mMonitorThread = null;

}

8. Directly sharing memory is not advisable but we can do it. The logic is identical to case 7 with named events but instead of writing/reading from registry, we access memory directly. It looks something like this:

// BOTH CLIENT & SERVER PROCESS NEED THESE

// Returns pointer to shared memory

private IntPtr ObtainHandleToSharedMemory(){

const uint PHYS_ADDR =0x80230000;//Make sure this is not used 

                                                 on your platform

const int MEM_SIZE = 10;


IntPtr hwnd = 

        Win32Api.VirtualAlloc(0, MEM_SIZE, Win32Api.MEM_RESERVE,

                  Win32Api.PAGE_READWRITE|Win32Api.PAGE_NOCACHE);

if (hwnd.ToInt32() != 0){					

    if (Win32Api.VirtualCopy(hwnd, PHYS_ADDR, MEM_SIZE, 

                (Win32Api.PAGE_READWRITE|Win32Api.PAGE_NOCACHE)) 

                                                       == true){

        return hwnd;

    }

}

MessageBox.Show(

             Marshal.GetLastWin32Error().ToString(),"Failed");

return IntPtr.Zero;

}

// Define common structure/class in both client and server e.g.

private class SharedMemory{

public byte b1;

public byte b2;

public char c;

public bool flag;

public int i;

    
public SharedMemory(bool aFlag){

    flag=aFlag;

    if (aFlag){

             b1=1;b2=2;c='!';i=3;

    }else{

        b1=0;b2=0;c=' ';i=0;

    }

}


public override string ToString() {

    return "b1=" + b1.ToString() + ", b2="+b2.ToString() 

                            + ", c=" + c + ", i=" + i.ToString();

}

}

// CLIENT

// As in previous example but instead of reading the registry

// read the following in MonitorOtherProc

IntPtr memHwnd=ObtainHandleToSharedMemory();

if (memHwnd.ToInt32() !=0 ){

    SharedMemory sm=new SharedMemory(false);

    Marshal.PtrToStructure(memHwnd,sm);

    MessageBox.Show(sm.ToString(),sm.flag.ToString());

}

// SERVER

// As in previous example but instead of writing to registry

// do the following in cmdWrite_Click

IntPtr memHwnd=ObtainHandleToSharedMemory();

if (memHwnd.ToInt32() !=0 ){

    SharedMemory sm=new SharedMemory(true);

    Marshal.StructureToPtr(sm,memHwnd,false);

}