【发布时间】:2015-11-06 15:26:02
【问题描述】:
每个人。我的团队目前正在开发一个涉及两个部分的系统:C# 中的数据组织、UI 等,以及由于性能要求而在 C 中进行大量数字运算。我们正在尝试压缩性能的每一点,所以虽然最初我们使用文件与两个进程通信,但我们正在通过 IPC 通信这两个进程来继续前进。专门命名的管道。传输 C 程序所需数据的 C# 程序的简化版本是这样的:
String pipeName = "some_random_name";
NamedPipeServerStream pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.Out, 2, PipeTransmissionMode.Byte, PipeOptions.None, 0, 4096);
Process someProcess= new Process();
someProcess.StartInfo.FileName = appDirectory + "someProcess.exe";
someProcess.StartInfo.RedirectStandardInput = true;
someProcess.StartInfo.RedirectStandardOutput = true;
someProcess.StartInfo.RedirectStandardError = false;
someProcess.StartInfo.UseShellExecute = false;
someProcess.StartInfo.Arguments = "\\\\.\\pipe\\" + pipeName;
someProcess.Start();
someProcess.PriorityClass = ProcessPriorityClass.RealTime;
pipeServer.WaitForConnection();
pipeServer.Write(BitConverter.GetBytes(lengthOfNextDataSent), 0, 4);
pipeServer.WaitForPipeDrain();
for (i = 0; i < lengthOfNextDataSent; i++){
byte[] xBytes = BitConverter.GetBytes(SomeOtherIntegerData);
pipeServer.Write(xBytes , 0, xBytes.Length);
}
而简化的客户端 C 代码是:
fd = open(argv[1], O_RDONLY);
read(fd, &received_length, sizeof(int));
for(i = 0; i < received_length; i++){
read(fd, integer_array[i], 16);
}
close(fd);
奇怪的是,我能够正确接收(在 C 应用程序中)并解码多达 1820~ 个字节。如果我尝试调用 C# 方法 WaitForPipeDrain 或在写入 1820~ 字节后尝试刷新(在较小的块中,整数大小或更大),则会引发“管道损坏”异常。如果我尝试在一次调用中写入比这更多的字节,则 C 应用程序在读取时会崩溃。
编辑:一个我忘了提的细节。我正在使用 mingw32-64 编译器在类似 cygwin 的环境(特别是 msys2)中编译 C 程序。
你能告诉我我做错了什么吗?
【问题讨论】:
-
我很确定这不是您正确序列化数据的方式。还有,你是怎么在C程序中分配
integer_array[]的? -
我只是发送整数。哪种方式是正确的做法?我尝试在 C 中使用 read 方法,使用单个整数作为接收缓冲区,分配为 char * buf 的 char 数组缓冲区; buf = (char *) malloc ( expected_size * sizeof(int) );或者简单地说:char buf[someSize];
-
如果你读的是整数,为什么不
read(fd, ..., sizeof(int)? -
如果您想要高性能,请将 C 代码置于进程中(在 DLL 中,使用 p/invoke)
-
EOF:这就是我第一次尝试读取整数的方式。有那么一刻,我认为 sizeof 的结果在 c# 和 C 中给了我不同的结果,所以我硬编码了大小。无论 sizeof(int) 如何,行为都是相同的。 Ben:C 代码非常复杂,而且不是线程安全的。因此,当我们尝试在 DLL 中执行多个代码实例时遇到了问题。我们可以修改 C 代码,但由于时间限制,它很大,而且不是一个非常可行的目标。
标签: c# c ipc named-pipes