¿Cómo hago que las canalizaciones con nombre funcionen entre c ++ y .NET?

Me fue muy difícil hacer que Named Pipes funcione entre c ++ y .NET. No tuve problemas para crear Canalizaciones con nombre que funcionaran entre 2 aplicaciones c ++ o entre 2 aplicaciones .NET.

No tengo problemas con esta comunicación, uso este escenario en algún proyecto.

Lado de C ++:

LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\pipename"); CHAR chReadBuf[1024]; DWORD cbRead; BOOL fResult; fResult = CallNamedPipe( lpszPipename, // pipe name _Message, // message to server strlen(_Message), // message length chReadBuf, // buffer to receive reply sizeof(chReadBuf), // size of read buffer &cbRead, // number of bytes read NMPWAIT_WAIT_FOREVER); // wait;-) 

En el lado C #:

  public string GetMessageFromPipe() { int _lenght = 0; /* * Pipe Control Block */ _pipeserver.WaitForConnection(); do { _lenght += _pipeserver.Read(_buffer, _lenght, _buffer.Length); } while (!_pipeserver.IsMessageComplete); _pipeserver.Disconnect(); /* * End of Pipe Control Block */ if (_lenght == 0) { throw new ArgumentException("Message is empty ;-("); } return Encoding.UTF8.GetString(_buffer, 0, _lenght); } 

Creación de la tubería:

 _pipeserver = new NamedPipeServerStream("pipename", PipeDirection.InOut, 254, PipeTransmissionMode.Message, PipeOptions.Asynchronous, 262144, 262144); 

Descubrí que podía usar ProcessExplorer para ver los nombres de las canalizaciones que estaba abriendo. Aunque utilicé exactamente el mismo nombre en c ++ y .NET, ProcessExplorer mostró que eran diferentes.

Terminé usando estos nombres: En .NET: “\\. \ Pipe \ XXXDebug”

En c ++: “\\. \ Pipe \ pipe \ XXXDebug”

Lo que vi en ProcessExplorer para ambos fue: \ Device \ NamedPipe \ pipe \ XXXDebug

Una cosa más, abrí la tubería en .NET a través de:

NamedPipeServerStream pipe = new NamedPipeServerStream (_pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte);

Y abrí la tubería en c ++ a través de:

  g_hPipe = CreateFile( _pipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);