我最近一直在琢磨C#和c++之间利用命名管道通信进行进程通信的问题。有几个个问题困扰了我很久,一直没有得到解决:1. c++命名管道之间数据传递是否只能通过字符串形式来传递?如果是int[]数组该怎么传?
看msdn以及网上众多的例子,命名管道通信,都只是传递一个简单的字符串,如果传递的是一个非常大的整形数组怎么传?比如说int[10000]该怎么传?
发送端: char szMsg[80] = "test string!\n";
DWORD  dwSize = 80, dwBytesWritten = 0;
BOOL ret = FALSE;
ret = ::WriteFile(hPipe, szMsg, strlen(szMsg) + 1, &dwBytesWritten, NULL);
ShowInfo("发送完毕,\r\n");接收端: char szMsg[80] = "";
        DWORD  dwSize = 80, dwBytesRead = 0;
ret = ReadFile(dlg->hPipe, szMsg, dwSize, &dwBytesRead, NULL);
这样没有问题。
但是如果将传递的数据改为int[]数组,如int szMsg[80] = {1,2,3,4,5,6},就不行了?
通过char[]形式传递指针,通过int[]也是传递指针,但为什么就行不通呢?
int[]数组该怎么传?
2. c#中命名管道之间数据传递是否只能用byte[]字节数组的形式来传递呢?
在C#中调用API:
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteFile(
            IntPtr hHandle, // handle to file
            byte[] lpBuffer,// data buffer
            uint nNumberOfBytesToWrite, // number of bytes to write
            byte[] lpNumberOfBytesWritten, // number of bytes written
            uint lpOverlapped // overlapped buffer
            );
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ReadFile(
            IntPtr hHandle, // handle to file
            byte[] lpBuffer,// data buffer
            uint nNumberOfBytesToRead,// number of bytes to read
            byte[] lpNumberOfBytesRead,// number of bytes read
            uint lpOverlapped// overlapped buffer
            );
如果将传递的数据以byte[]的形式传递,两个进程之间通信没有任何问题。
但是,如果将上面WriteFile和ReadFile中的byte[]改成cahr[]形式:
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteFile(
            IntPtr hHandle, // handle to file
            char[] lpBuffer,// data buffer
            uint nNumberOfBytesToWrite, // number of bytes to write
            char[] lpNumberOfBytesWritten, // number of bytes written
            uint lpOverlapped // overlapped buffer
            );
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ReadFile(
            IntPtr hHandle, // handle to file
            char[] lpBuffer,// data buffer
            uint nNumberOfBytesToRead,// number of bytes to read
            char[] lpNumberOfBytesRead,// number of bytes read
            uint lpOverlapped// overlapped buffer
            );
将要传递的数据转换成char[]的形式来传递,两个进程就不能通信了。就是在发送端WriteFile能够发送出去,接收端ReadFile不能读出数据。
我尝试过用c#发送数据char[]形式或者string,在c++端都能够接收,只是c#端却不能接收。
c#中命名管道之间数据传递是否只能用byte[]字节数组的形式来传递呢?3. 综上,命名管道到底是以何种方式传递数据?字节吗?
CreateNamedPipeA(
    LPCSTR lpName,
    DWORD dwOpenMode,//duplex, inbound, or outbound)
    DWORD dwPipeMode,//byte-type or message-type)
    DWORD nMaxInstances,//最大的管道实例数目
    DWORD nOutBufferSize,//
    DWORD nInBufferSize,
    DWORD nDefaultTimeOut,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes
    );
其中第三个参数dwPipeMode决定了管道中数据的传递方式byte-type or message-type。字节模式和消息模式分别是以什么形式来传递数据呢?
恳请您给我解答,谢谢!

解决方案 »

  1.   

    1:可以把int[10000]中的每一个元素使用16进制字符串表示,然后把这些16进制的字符串来传递就是了。比如123可以使用0x7B来表示。为了每一个元素的16进制字符串长度相等,可以使用3位或4位,比如123=0x07B,或0x007B.
    在接收端按字符串长度分开处理就是了。当然,你可以使用其它的方式,经如把一个int类型的元素使用两个Byte来表示,然后把Byte按Char来处理,也是一种方法。2:我并不太清楚命名管道的用法,不过我想传递上只能通过byte数组。
    3:字节吗?我想是的。
      

  2.   

    1:可以把int[10000]中的每一个元素使用16进制字符串表示,然后把这些16进制的字符串来传递就是了。比如123可以使用0x7B来表示。为了每一个元素的16进制字符串长度相等,可以使用3位或4位,比如123=0x07B,或0x007B.
    在接收端按字符串长度分开处理就是了。当然,你可以使用其它的方式,经如把一个int类型的元素使用两个Byte来表示,然后把Byte按Char来处理,也是一种方法。2:我并不太清楚命名管道的用法,不过我想传递上只能通过byte数组。
    3:字节吗?我想是的。
      

  3.   


    谢谢你!
    关于第一个问题,要传一个int[10000],如果按照你说的方法,其中有10000个整数,那么就得传10000次了,因为管道每次writefile()只能写一个char[],这样的话效率会不会太低了呢?谢谢!