How to send messages between c++ .dll and C# app using named pipe?

前端 未结 1 830
深忆病人
深忆病人 2021-01-31 12:38

I\'m making an injected .dll written in C++, and I want to communicate with a C# app using named pipes.

Now, I am using the built in System.IO.Pipe .net classes in the C

相关标签:
1条回答
  • 2021-01-31 13:40

    A few things.

    1- Are you using the same pipe name
    C++ : "\\.\pipe\HyperPipe"
    C# : "HyperPipe"

    2- I think on the C# side it might be better to use ReadToEnd(), I have only used named pipes in C++, but I assume that ReadToEnd() will read a message since you are using message based pipes.

    3- On the C++ side, you are trying to use non-blocking pipes and polling the pipe for connection and data etc. I would suggest one of three things.

      a - Use a blocking pipe on a separate thread or
      b - Use non blocking pipes using Overlapped IO
      c - Use non blocking pipes using IOCompletion ports
    

    The first option would be the easiest and for what it sounds like you are doing, it will scale fine. Here is a link to a simple sample to (a) http://msdn.microsoft.com/en-us/library/aa365588(VS.85).aspx

    4- Make sure that your encodings match on both sides. For example, if your C++ code is compiled for Unicode, you must read the Pipe stream on the C# side using Unicode encoding. Some thing like the following.

    using (StreamReader rdr = new StreamReader(pipe, System.Text.Encoding.Unicode))
    {
      System.Console.WriteLine(rdr.ReadToEnd());
    }
    

    Update: Since I had not worked with this in C# I thought I would write a small test. Just using blocking pipes no threading or anything, just to confirm the basics work, here is the very rough test code.

    C++ Server

    #include <tchar.h>
    #include <windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
      HANDLE hPipe = ::CreateNamedPipe(_T("\\\\.\\pipe\\HyperPipe"),
        PIPE_ACCESS_DUPLEX,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
        PIPE_UNLIMITED_INSTANCES,
        4096,
        4096,
        0,
        NULL);
    
    
      ConnectNamedPipe(hPipe, NULL);
    
      LPTSTR data = _T("Hello");
      DWORD bytesWritten = 0;
      WriteFile(hPipe, data, _tcslen(data) * sizeof(TCHAR), &bytesWritten, NULL);
      CloseHandle(hPipe);
      return 0;
    }
    

    C# Client

    using System;
    using System.Text;
    using System.IO;
    using System.IO.Pipes;
    
    namespace CSPipe
    {
      class Program
      {
        static void Main(string[] args)
        {
          NamedPipeClientStream pipe = new NamedPipeClientStream(".", "HyperPipe", PipeDirection.InOut);
          pipe.Connect();
          using (StreamReader rdr = new StreamReader(pipe, Encoding.Unicode))
          {
            System.Console.WriteLine(rdr.ReadToEnd());
          }
    
          Console.ReadKey();
        }
      }
    }
    
    0 讨论(0)
提交回复
热议问题