c++进程和C#进程之间利用命名管道通信的问题

先之 2008-06-12 11:43:02
我最近一直在琢磨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。字节模式和消息模式分别是以什么形式来传递数据呢?


恳请您给我解答,谢谢!
...全文
1118 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
火星大能猫 2012-11-02
  • 打赏
  • 举报
回复
表示关注
先之 2008-06-23
  • 打赏
  • 举报
回复
算了,就这么结贴了!
sxmonsy 2008-06-18
  • 打赏
  • 举报
回复
关注+学习 关注+学习 关注+学习 关注+学习
先之 2008-06-18
  • 打赏
  • 举报
回复
似乎没有好的答案啊!
失望……
Jade_2008 2008-06-12
  • 打赏
  • 举报
回复
帮顶!!!
czw5305302 2008-06-12
  • 打赏
  • 举报
回复
Good Question, mark first
先之 2008-06-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hbxtlhx 的回复:]
1:可以把int[10000]中的每一个元素使用16进制字符串表示,然后把这些16进制的字符串来传递就是了。比如123可以使用0x7B来表示。为了每一个元素的16进制字符串长度相等,可以使用3位或4位,比如123=0x07B,或0x007B.
在接收端按字符串长度分开处理就是了。

当然,你可以使用其它的方式,经如把一个int类型的元素使用两个Byte来表示,然后把Byte按Char来处理,也是一种方法。

2:我并不太清楚命名管道的用法,不过我想传…
[/Quote]

谢谢你!
关于第一个问题,要传一个int[10000],如果按照你说的方法,其中有10000个整数,那么就得传10000次了,因为管道每次writefile()只能写一个char[],这样的话效率会不会太低了呢?谢谢!
北京的雾霾天 2008-06-12
  • 打赏
  • 举报
回复
1:可以把int[10000]中的每一个元素使用16进制字符串表示,然后把这些16进制的字符串来传递就是了。比如123可以使用0x7B来表示。为了每一个元素的16进制字符串长度相等,可以使用3位或4位,比如123=0x07B,或0x007B.
在接收端按字符串长度分开处理就是了。

当然,你可以使用其它的方式,经如把一个int类型的元素使用两个Byte来表示,然后把Byte按Char来处理,也是一种方法。

2:我并不太清楚命名管道的用法,不过我想传递上只能通过byte数组。
3:字节吗?我想是的。
北京的雾霾天 2008-06-12
  • 打赏
  • 举报
回复
1:可以把int[10000]中的每一个元素使用16进制字符串表示,然后把这些16进制的字符串来传递就是了。比如123可以使用0x7B来表示。为了每一个元素的16进制字符串长度相等,可以使用3位或4位,比如123=0x07B,或0x007B.
在接收端按字符串长度分开处理就是了。

当然,你可以使用其它的方式,经如把一个int类型的元素使用两个Byte来表示,然后把Byte按Char来处理,也是一种方法。

2:我并不太清楚命名管道的用法,不过我想传递上只能通过byte数组。
3:字节吗?我想是的。
先之 2008-06-12
  • 打赏
  • 举报
回复
盼望得到大家解答!
客户端安装个软件。负责监控该电脑的打印动作。并把内容转成图片储存。并将图片传送到服务器机器上,并将打印内容传到服务器上面. 解决方案: 1. 先用api打印函数连接到指定的打印机.再试着用枚举函数()获得打印作业信息.根据信息得知打印的内容,及当前的状态. 2. 获知内容,得知打印内容所在的位置,再某种方式将数据导在图片;再传到服务器上. 技术问题: 1. 打印枚举函数中找不到JOB_INFO_1 或 JOB_INFO_2结构的定义.(已解决) 2. 怎么样获得打印内容.是通过原本的驱动还是其它办法, 其它: 文件传给pdf打印机之前已经存成raw格式了,应该是从缓冲池中直接读取数据 接下去要完成的应该是怎么把raw格式读出来, 具我推测在获得打印信息的时候肯定有某个参数跟这个RAW格式是对应的.读出某个参数后才能再继续读取对RAW文件读取 具微软件网站显示,打印机的格式应该分成5种.raw的三种格式,text,emf(增强型图元文件) RAW格式指是最原始的数据 CreateDC("WINSPOOL", printer, null, ref dv);//用DISPLAY,是获取整个屏幕的设备场景;2、用WINSPOOL,则是访问打印驱动 返回新设备场景句柄,若出错则为零 EMFStreamPrintDocument 实力问题:就算获得句柄也没有办法接下去要做什么.(想错了) 目前状态:EMF图片取出来,监控也可以实现了.但监控的打印作业跟EMF图片不知道怎么产生关联.而且EMF图片读起出来比较慢. 取EMF图片本身spl就已经读入内存,但是有一种办法为了要读取图片只能将spl文件考出来再做成emf文件. 新的思路能不能将文件 shd文件中包含了一个作业ID RPC 命名管道 Server(服务器) Server 系统服务提供 RPC 支持以及文件、打印和命名管道在网络上的共享。Server 服务允许本地资源(如磁盘和打印机)共享,因此网络上的其他用户可以访问它们。它还允许在其他计算机上的应用程序与您计算机上的应用程序之间进行命名管道通信,这是用于 RPC 的。命名管道通信是为一个进程的输出(此输出用作另外一个进程的输入)而保留的内存。接受输入的进程不必是本地进程

110,577

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧