Introduction
In general, inter-process communication is a mechanism that allows processes to communicate with each other. The IPC methods vary depending on the operating systems we rely on. Here, I have used named pipes for the implementation purpose where we will be sending data from a C++ process to C# process.
Creating a NamedPipe
Install/enable the required DLL's in Visual Studio. The code below is used to create a pipe NamedPipeServer.cs in C#.
Importing the kernel32.dll for creating pipe. Pipe will be listening for the incoming data immediately once the connection has been established.
using System;
using Microsoft.Win32.SafeHandles;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Collections;
namespace CSNamedPipe {
public class NamedPipeServer {
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateNamedPipe(String pipeName, uint dwOpenMode, uint dwPipeMode, uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut, IntPtr lpSecurityAttributes);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int ConnectNamedPipe(SafeFileHandle hNamedPipe, IntPtr lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int DisconnectNamedPipe(SafeFileHandle hNamedPipe);
public
const uint DUPLEX = (0x00000003);
public
const uint FILE_FLAG_OVERLAPPED = (0x40000000);
public class Client {
public SafeFileHandle handle;
public FileStream stream;
}
public
const int BUFFER_SIZE = 100;
public Client clientse = null;
public string pipeName;
Thread listenThread;
SafeFileHandle clientHandle;
public NamedPipeServer(string PName) {
pipeName = PName;
}
public void Start() {
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
//ListenForClients();
//Read();
}
private void ListenForClients() {
while (true) {
clientHandle = CreateNamedPipe(this.pipeName, DUPLEX | FILE_FLAG_OVERLAPPED, 0, 255, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
//could not create named pipe
if (clientHandle.IsInvalid) return;
int success = ConnectNamedPipe(clientHandle, IntPtr.Zero);
//could not connect client
if (success == 0) return;
clientse = new Client();
clientse.handle = clientHandle;
clientse.stream = new FileStream(clientse.handle, FileAccess.Read, BUFFER_SIZE, true);
Thread readThread = new Thread(new ThreadStart(Read));
readThread.Start();
}
}
private void Read() {
string temp;
Queue q = new Queue();
byte[] buffer = null;
ASCIIEncoding encoder = new ASCIIEncoding();
while (true) {
int bytesRead = 0;
try {
buffer = new byte[BUFFER_SIZE];
bytesRead = clientse.stream.Read(buffer, 0, BUFFER_SIZE);
} catch {
Console.WriteLine("read error");
break;
}
//client has disconnected
if (bytesRead == 0) break;
int ReadLength = 0;
for (int i = 0; i < BUFFER_SIZE; i++) {
if (buffer[i].ToString("x2") != "cc") {
ReadLength++;
} else break;
}
if (ReadLength > 0) {
byte[] Rc = new byte[ReadLength];
Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
temp = encoder.GetString(Rc, 0, ReadLength);
q.Enqueue(temp);
Console.WriteLine("Element Inserted :" + temp);
Console.WriteLine("Current queue");
foreach(string c in q) {
Console.Write(c + " ");
}
//buffer.Initialize();
}
}
clientse.stream.Close();
clientse.handle.Close();
}
}
}


Join the conversation! Your thoughts help the community grow.