Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过SendMessage执行IPC时,如何处理32位/64位不匹配? < >我有一段C++代码,它使用窗口消息读取树项(如在一个平面中包含的文本)。接收mesage的树视图处于不同的进程中,因此我使用了一点共享内存作为窗口消息的一个参数所指向的结构。我必须做这项工作,因为远程进程不在我的控制之下(我正在编写一个类似于Spy++的应用程序)_C++_Windows_Winapi_Sendmessage - Fatal编程技术网

通过SendMessage执行IPC时,如何处理32位/64位不匹配? < >我有一段C++代码,它使用窗口消息读取树项(如在一个平面中包含的文本)。接收mesage的树视图处于不同的进程中,因此我使用了一点共享内存作为窗口消息的一个参数所指向的结构。我必须做这项工作,因为远程进程不在我的控制之下(我正在编写一个类似于Spy++的应用程序)

通过SendMessage执行IPC时,如何处理32位/64位不匹配? < >我有一段C++代码,它使用窗口消息读取树项(如在一个平面中包含的文本)。接收mesage的树视图处于不同的进程中,因此我使用了一点共享内存作为窗口消息的一个参数所指向的结构。我必须做这项工作,因为远程进程不在我的控制之下(我正在编写一个类似于Spy++的应用程序),c++,windows,winapi,sendmessage,C++,Windows,Winapi,Sendmessage,这在原则上运行良好,但在目标流程实质上不同的情况下失败: 如果目标进程的代码是使用UNICODE定义构建的,但我自己的代码不是,那么这两个进程将对进程中字符串成员的结构有不同的想法。我已经通过一个调用解决了这个问题,然后明确地发送了TVM\u GETITEMA或TVM\u GETITEMW(如果需要,记录结果) 如果调用进程是以32位模式构建的,而目标进程是64位(或者反过来),那么结构的布局(和大小)是不同的,因为指针的大小不同 我目前正试图找到解决第二个问题的好方法。这个特定的用例(获取树项

这在原则上运行良好,但在目标流程实质上不同的情况下失败:

  • 如果目标进程的代码是使用UNICODE定义构建的,但我自己的代码不是,那么这两个进程将对进程中字符串成员的结构有不同的想法。我已经通过一个调用解决了这个问题,然后明确地发送了
    TVM\u GETITEMA
    TVM\u GETITEMW
    (如果需要,记录结果)

  • 如果调用进程是以32位模式构建的,而目标进程是64位(或者反过来),那么结构的布局(和大小)是不同的,因为指针的大小不同

  • 我目前正试图找到解决第二个问题的好方法。这个特定的用例(获取树项文本)只是一个例子,我的代码正在发送的其他窗口消息也存在同样的问题。现在,我正在考虑两种方法:

  • 构建我的代码两次,然后根据目标进程的操作执行32位或64位代码。这需要对我们的构建和打包系统进行一些更改,并且需要将特定于体系结构的代码分解成一个专用的进程(现在它位于DLL中)。一旦这样做了,它应该可以很好地工作
  • 在运行时检测目标进程的映像格式,然后使用自定义结构,而不是明确使用32位或64位宽指针的结构。这需要编写代码来检测远程进程的体系结构(我希望可以通过调用远程进程,然后使用分析PE头来实现),并硬编码两个结构(一个具有32位指针,一个具有64位指针)。此外,我必须确保共享内存地址在32位地址空间中(这样我自己的代码就可以随时访问它,即使它是以32位模式编译的)

  • 还有其他人必须解决类似的问题吗?有更简单的解决方案吗?

    我想有设计问题。我不知道你为什么要这样做,也许你不能完全控制所有部分。但从基本的MVC角度来看,您是在从视图中窥视值,而不是向模型询问值。

    我不熟悉这条特定消息,但是如果Windows TVM_GETITEM消息应该在多个进程中正常运行,然后Windows应该在调用方的地址空间中填充TVTItem结构,并为您处理任何需要的转换,而不需要您提供共享内存。如果不是,那么我怀疑你在这里看到的问题是很容易解决的,没有一些不舒服的扭曲


    共享内存位让我困惑;通常,您必须使这两个进程明确地知道共享内存段,并且您没有提到DLL注入或类似的内容。被调用方如何确切地知道其地址空间中的共享内存部分,以及您如何使用它?你确定这个API需要它吗?

    我在运行时检查远程进程是32位还是64位,然后在发送消息之前将正确的结构写入共享内存

    例如,下面是如何使用
    TVM_GETITEM
    消息,即使消息的调用者和接收者之间存在32位64位的混淆:

    /* This template is basically a copy of the TVITEM struct except that
     * all fields which return a pointer have a variable type. This allows
     * creating different types for different pointer sizes.
     */
    template <typename AddrType>
    struct TVITEM_3264 {
      UINT      mask;
      AddrType  hItem;
      UINT      state;
      UINT      stateMask;
      AddrType  pszText;
      int       cchTextMax;
      int       iImage;
      int       iSelectedImage;
      int       cChildren;
      AddrType  lParam;
    };
    typedef TVITEM_3264<UINT32> TVITEM32;
    typedef TVITEM_3264<UINT64> TVITEM64;
    
    // .... later, I can then use the above template like this:
    LPARAM _itemInfo;
    DWORD pid;
    ::GetWindowThreadProcessId( treeViewWindow, &pid );
    if ( is64BitProcess( pid ) ) {
        TVITEM64 itemInfo;
        ZeroMemory( &itemInfo, sizeof( itemInfo ) );
    
        itemInfo.mask = TVIF_HANDLE | TVIF_TEXT;
        itemInfo.hItem = (UINT64)m_item;
        itemInfo.pszText = (UINT64)(LPTSTR)sharedMem->getSharedMemory( sizeof(itemInfo) );
        itemInfo.cchTextMax = MaxTextLength;
        _itemInfo = (LPARAM)sharedMem->write( &itemInfo, sizeof(itemInfo) );
    } else {
        TVITEM32 itemInfo;
        ZeroMemory( &itemInfo, sizeof( itemInfo ) );
    
        itemInfo.mask = TVIF_HANDLE | TVIF_TEXT;
        itemInfo.hItem = (UINT32)m_item;
        itemInfo.pszText = (UINT32)(LPTSTR)sharedMem->getSharedMemory( sizeof(itemInfo) );
        itemInfo.cchTextMax = MaxTextLength;
        _itemInfo = (LPARAM)sharedMem->write( &itemInfo, sizeof(itemInfo) );
    }
    
    /*此模板基本上是TVTItem结构的副本,除了
    *返回指针的所有字段都具有变量类型。这允许
    *为不同的指针大小创建不同的类型。
    */
    模板
    结构TVITEM_3264{
    核弹头面罩;
    AddrType-hItem;
    乌因州;
    UINT状态掩码;
    添加类型pszText;
    int-cchTextMax;
    国际图像;
    int ISelecteImage;
    国际儿童;
    添加类型LPRAM;
    };
    类型定义TVITEM_3264 TVITEM32;
    类型定义TVTItem_3264 TVTItem64;
    // .... 稍后,我可以像这样使用上述模板:
    LPARAM_itemInfo;
    德沃德pid;
    ::GetWindowThreadProcessId(TreeView、Windows和pid);
    if(IS64位进程(pid)){
    tviitem64项目信息;
    零内存(&itemInfo,sizeof(itemInfo));
    itemInfo.mask=TVIF_句柄| TVIF_文本;
    itemInfo.hItem=(UINT64)m_项;
    itemInfo.pszText=(UINT64)(LPTSTR)sharedMem->getSharedMemory(sizeof(itemInfo));
    itemInfo.cchTextMax=MaxTextLength;
    _itemInfo=(LPARAM)sharedMem->write(&itemInfo,sizeof(itemInfo));
    }否则{
    tviitem32项目信息;
    零内存(&itemInfo,sizeof(itemInfo));
    itemInfo.mask=TVIF_句柄| TVIF_文本;
    itemInfo.hItem=(UINT32)m_项;
    itemInfo.pszText=(UINT32)(LPTSTR)sharedMem->getSharedMemory(sizeof(itemInfo));
    itemInfo.cchTextMax=MaxTextLength;
    _itemInfo=(LPARAM)sharedMem->write(&itemInfo,sizeof(itemInfo));
    }
    

    sharedMem->getSharedMemory
    函数是一个小助手函数,用于获取指向共享内存区域的指针;可选函数参数指定偏移量值。重要的是,共享内存区域应始终位于32位地址空间中(这样即使是32位远程进程也可以访问它)。

    我必须完成所有这些工作,因为接收进程确实不在我的控制之下。我正在开发一个类似Spy++的应用程序。对不起,我应该在前面提到这个问题,我相应地补充了这个问题。不幸的是,只有16位窗口(如
    LB_GETTEXT
    )可用的窗口消息才能在进程间正常工作。系统在后台进程之间复制数据。Th