如何使用命名管道在 c++ .dll 和 C# 应用程序之间发送消息?

2024-03-27

我正在制作一个用 C++ 编写的注入 .dll,并且我想使用命名管道与 C# 应用程序进行通信。

现在,我在 C# 应用程序中使用内置的 System.IO.Pipe .net 类,并在 C++ 中使用常规函数。

我在 C++ 方面没有太多经验(阅读:这是我的第一个 C++ 代码..),但我在 C# 方面经验丰富。

看来与服务器和客户端的连接正常,唯一的问题是消息没有发送。我尝试将 .dll 设置为服务器,将 C# 应用程序设置为服务器,将管道方向设置为 InOut(双工),但似乎都不起作用。

当我尝试将 .dll 设置为服务器(向 C# 应用程序发送消息)时,我使用的代码如下:

DWORD ServerCreate() // function to create the server and wait till it successfully creates it to return.
{
    hPipe = CreateNamedPipe(pipename,//The unique pipe name. This string must have the following form:  \\.\pipe\pipename
    PIPE_ACCESS_DUPLEX, 
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, //write and read and return right away
    PIPE_UNLIMITED_INSTANCES,//The maximum number of instances that can be created for this pipe
    4096 , // output time-out 
    4096 , // input time-out 
    0,//client time-out 
    NULL);

   if(hPipe== INVALID_HANDLE_VALUE)
   {
    return 1;//failed
   }
   else
    return 0;//success
}

void SendMsg(string msg)
{
    DWORD cbWritten;
    WriteFile(hPipe,msg.c_str(), msg.length()+1, &cbWritten,NULL);
}

void ProccesingPipeInstance()
{
    while(ServerCreate() == 1)//if failed
{
    Sleep(1000);    
}

//if created success, wait to connect
ConnectNamedPipe(hPipe, NULL);
for(;;)
{
    SendMsg("HI!");
    if( ConnectNamedPipe(hPipe, NULL)==0)
        if(GetLastError()==ERROR_NO_DATA)
        {
            DebugPrintA("previous closed,ERROR_NO_DATA");
            DisconnectNamedPipe(hPipe);
            ConnectNamedPipe(hPipe, NULL);
        }
    Sleep(1000);

}

C# 客户端是这样的:

static void Main(string[] args)
    {
        Console.WriteLine("Hello!");

        using (var pipe = new NamedPipeClientStream(".", "HyprPipe", PipeDirection.In))
        {
            Console.WriteLine("Created Client!");

            Console.Write("Connecting to pipe server in the .dll ...");
            pipe.Connect();

            Console.WriteLine("DONE!");

            using (var pr = new StreamReader(pipe))
            {
                string t;
                while ((t = pr.ReadLine()) != null)
                {
                    Console.WriteLine("Message: {0}",t);
                }
            }
        }
    }

我看到 C# 客户端连接到 .dll,但它不会收到任何消息。 正如我之前所说,我尝试以相反的方式进行操作,并尝试让 C# 向 .dll 发送消息,这将在消息框中显示它们。 .dll 被注入并连接到 C# 服务器,但当它收到消息时,它只是使注入的应用程序崩溃。

请帮助我,或指导我如何在 C++ 和 C# 应用程序之间使用命名管道


一些东西。

1-您是否使用相同的管道名称
C++:“\\.\pipe\HyperPipe”
C#:“超级管道”

2-我认为在 C# 方面,使用 ReadToEnd() 可能更好,我只在 C++ 中使用过命名管道,但我认为 ReadToEnd() 会读取消息,因为您正在使用消息 为基础的管道。

3-在C++方面,您尝试使用非阻塞管道并轮询管道以获取连接和数据等。我建议三件事之一。



  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
  

第一个选项是最简单的,对于听起来你正在做的事情来说,它会很好地扩展。这是一个简单示例的链接 (a)http://msdn.microsoft.com/en-us/library/aa365588(VS.85).aspx http://msdn.microsoft.com/en-us/library/aa365588(VS.85).aspx

4- 确保双方的编码匹配。例如,如果您的 C++ 代码是针对 Unicode 编译的,则必须使用 Unicode 编码读取 C# 端的 Pipe 流。 像下面这样的一些事情。

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

Update:由于我没有在 C# 中使用过这个,所以我想我应该编写一个小测试。只是使用阻塞管道,没有线程或任何东西,只是为了确认基础工作,这里是非常粗略的测试代码。

C++服务器

#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# 客户端

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();
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用命名管道在 c++ .dll 和 C# 应用程序之间发送消息? 的相关文章

随机推荐

  • 替换 DataFrame 索引中的 NaN

    我有一个数据框 如下所示 one two a 2 5 b 3 6 NaN 0 0 如何用字符串替换索引中的 NaN 例如 无标签 I tried df df replace np NaN No label and df index df i
  • 从嵌套 javascript 对象中删除属性的最佳方法是什么?

    我有一个树对象 如下所示 我尝试删除 items 数组属性 如果它为空 我不确定执行此操作的最佳方法是什么 我正在考虑循环遍历密钥 检查属性 然后删除使用delete myJSONObject prop 欢迎任何想法 想法吗 text Tr
  • 使用.Net MVC,如何列出播放不同文件的多个html音频播放器?

    我和我的朋友正在使用 Net 开发一个大学项目 我们正在尝试建立一个网站 允许用户以类似于 Soundcloud 等网站的方式收听音频剪辑 目前 我们有一个基本的 MVC 站点 允许用户将音频上传到服务器文件系统 并在数据库表中记录有关该文
  • 通过 bash 过滤 json - 不区分大小写

    我有 json 代码 需要通过属性的值对其进行过滤DNSName 过滤器必须不区分大小写 我怎样才能做到这一点 有没有可能解决它jq 这就是我创建 json 代码的方式 aws elbv2 describe load balancers r
  • 当生成的存在类型过于复杂时,无形状 HList 上的 toList 会失败

    给出以下定义 class R T class A class B class C 这有效 val s1 new R A new R B HNil val r1 s1 toList r1 of type List R gt A with B
  • Flutter firebase 未初始化

    我收到这个错误 未处理的异常 PlatformException null error 主机平台为非空返回值返回空值 null null 我已经更新了 yaml 中的所有 firebase 包 但仍然有此错误 E flutter 11230
  • Angular2 单选按钮在生产中不起作用

    我最近使用 Visual Studio 2015 和 MVC 构建了一个 angular2 应用程序 该项目还托管 WEBAPI 和 Angular 代码 我使用此处显示的说明将 MS Build 与 Angular build 集成htt
  • 无法解析在 iPhone 中获取数据的 Web 服务

    我是电话编程新手 使用下面的代码我得到网络服务的响应 NSString soapMessage NSString stringWithFormat n
  • 可定制的夏令时规则

    任务是什么 根据项目规范 我需要计算特定时区偏移的 DST 规则 规则cannot通过标准仪器应用 例如date default timezone set 因为我们不能依赖软件配置 并且如果某些 DST 规则发生更改 也无法更新它 我拥有的
  • Java:LinkedBlockingQueue是否考虑消费者的顺序?

    我有 3 个线程 2 个消费者 ConsumerA and ConsumerB and a Producer 我也有一个LinkedBlockingQueue queue At t 1 ConsumerA调用queue take At t
  • 我如何从 JMapViewer 世界地图中获取鼠标单击位置

    我正在使用地图浏览器 http wiki openstreetmap org wiki JMapViewerjar 在 JPanel 上显示世界地图 在地图上我添加MapMarkerDot s这是 GPS 点 问题是当我单击MapMarke
  • ASP.NET Web App 和 C# 应用程序之间的双向通信

    我需要构建一个可以双向通信的网站和应用程序 我将使用 ASP NET 构建网站 并使用 C 构建应用程序 我将自己托管该网站 它将与应用程序在同一台计算机上运行 我不知道在两者之间发送数据的最佳技术是什么 C 应用程序需要一直运行 我应该构
  • firebase多位置更新用户身份验证和数据库

    我有一个用于注册新用户的表格 其中包含电子邮件 密码 全名和电话号码 我可以用firebase auth createUserWithEmailAndPassword如果成功则创建新用户 然后我用firebase database ref
  • python 2和3中的UTF-8字符串

    以下代码适用于 Python 3 people u Nicholas Gyeney u Andr xe9 writers join people print writers print Writers format writers 并产生以
  • Gmp PHP 扩展 - MAMP PRO

    我查看了其他几个问题 例如this one https stackoverflow com questions 50435455 how to install gmp extension for php 7 2 using mamp on
  • Django 中 GROUP BY 中注释的聚合

    UPDATE 感谢发布的答案 我找到了一种更简单的方法来表述问题 原问题可以在修订历史中看到 问题 我正在尝试将 SQL 查询转换为 Django 但收到一个我不明白的错误 这是我的 Django 模型 class Title models
  • 如何使用dos批处理文件命令将日期设置为当前日期

    如何使用 dos 批处理文件命令将日期设置为当前日期 如果您需要在批处理文件中使用当前日期 则变量 date 有当前日期 echo date 23 02 2010 它使用您计算机的区域设置的格式 在我的电脑里是dd mm yyyy 自从 不
  • CMake 在 include_directories 中找不到正确的头文件/包含文件

    当我尝试编译时 我再次收到 架构 x86 64 的未定义符号 错误 我已经尝试了比这篇文章中实际记录的更多的内容 因为我已经忘记了我尝试过的所有内容 这是一个非常简单的设置should使用 CMake 很容易编译 当我对此运行 make 时
  • 如何使用 javascript 知道图像是否已加载

    我正在编写一个显示相册的网站 该页面正在加载拇指并在每张图片完全加载之前在它们上应用白色叠加层 我在本地编写了这个代码 效果很好 但是在我的服务器上上传文件并加载页面会带来一些显示错误 一些白色覆盖层不会淡出 因为 jQueryload函数
  • 如何使用命名管道在 c++ .dll 和 C# 应用程序之间发送消息?

    我正在制作一个用 C 编写的注入 dll 并且我想使用命名管道与 C 应用程序进行通信 现在 我在 C 应用程序中使用内置的 System IO Pipe net 类 并在 C 中使用常规函数 我在 C 方面没有太多经验 阅读 这是我的第一