windows进程间的通信实战

windows进程间的通信实战手段,在堆中申请个内存这样另外的进程也可以使用,但是很可惜,在相同的地址内数据没有映射。内存地址再进程中是隔离的,每个不同的进程,内存地址是不会重复的,也不能共享。只有在高2G的系统地方才是共享的,所以微软的做法是把高进程内的》高2G-》另一个进程内存里面

窗口发消息

1) 自定义消息

先自定义一个消息发送给窗口

image.png

第一想到的当然是在堆中申请个内存这样另外的进程也可以使用

image.png

但是很可惜,在相同的地址内数据没有映射。内存地址再进程中是隔离的,每个不同的进程,内存地址是不会重复的,也不能共享。只有在高2G的系统地方才是共享的,所以微软的做法是把高进程内的》高2G-》另一个进程内存里面

微软里面有个API可以达到为别的进程开辟空间的

LPVOID VirtualAlloc(

  LPVOID lpAddress,        // region to reserve or commit

  SIZE_T dwSize,           // size of region

  DWORD flAllocationType,  // type of allocation

  DWORD flProtect          // type of access protection

);

image.png

最后释放空间

/VirtualFreeEx(hProcess, addr, 0x256, MEM_RELEASE);

对于上面的微软有个自定义消息WM_COPYDATA
SendMessage(

  (HWND) hWnd,              // handle to destination window //接收方句柄

  WM_COPYDATA,              // message to send

  (WPARAM) wParam,          // handle to window (HWND)//发送数据方的句柄

  (LPARAM) lParam           // data (PCOPYDATASTRUCT)

);

发送WM_COPYDATA消息只能使用Sendmessage不能使用PostMessage,

因为Post不会等处理完成再执行一条指令

image.png

dll共享节

1) 没有共享节导出全局变量

使用初始值为1

image.png

image.png

image.png

结论:没有共享。

1) 共享节导出全局变量

三种方法设定共享节的属性

pragma comment(linker,"/section:DLLSharedSection,rws")

/SECTION:DLLSharedSection,rws

DEF文件:

SETCTIONS
DLLSharedSection READ WRITE SHARED

image.png

pragma data_seg("MY_DATA")

int nDataBase = 1;

pragma data_seg()

image.png

文件映射

文件映射到内存就可以在内存中直接改数据,还能进程共享
   //第一步打开文件获得句柄
    HANDLE hand= CreateFileA("E:\\\\a.txt", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    //创建映射对象
    HANDLE MapHand= CreateFileMappingA(hand, NULL, PAGE_READWRITE, 0, 0, "Text");
    //把映射对象加载到内存
    LPVOID addr = MapViewOfFile(MapHand, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    //从内存中释放
UnmapViewOfFile(addr);


文件共享,在另一进程中使用
//打开文件映射对象,必须前面创建了名字
    HANDLE MapHand=OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, "Text");
    //加载到内存
    LPVOID addr = MapViewOfFile(MapHand, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    //卸载内存文件映射
UnmapViewOfFile(addr);

管道

image.png

一个程序的输出为另一个程序的输入

小例子cmd

HANDLE ReadHand;

_HANDLE_ WriteHand;

//创建管道

_BOOL_ bRet=_CreatePipe_(&ReadHand, &WriteHand, _NULL_, 0);

//对管道写东西

_DWORD_ dw;

_DWORD_ dwr;

char szBuf[256] = "hello word ";

char szBUF[256] = { 0 };

_WriteFile_(WriteHand, szBuf, _strlen_(szBuf) + 1, &dw, _NULL_);

//从管道读东西

ReadFile(ReadHand, szBUF, 256, &dwr, NULL);

image.png

//创建两个管道

_CreatePipe_(&CmdRead, &MyCmdWrite, &sa, _NULL_);

CreatePipe(&MyCmdRead, &CmdWrite, &sa, NULL);

把管道加入到进程里面

//打开cmd进程

_STARTUPINFOA_ si = { 0 };

si._cb_ = sizeof(_STARTUPINFOA_);

si._dwFlags_ = _STARTF_USESTDHANDLES_;

si._hStdInput_ = CmdRead;

si._hStdOutput_ = CmdWrite;

si._hStdError_ = CmdWrite;

_PROCESS_INFORMATION_ pi;

_CreateProcessA_(_NULL_, "cmd.exe", _NULL_, _NULL_, _TRUE_, _CREATE_NO_WINDOW_, _NULL_, _NULL_, &si, &pi);

image.png

转载请说明出处
草堂教程网 » windows进程间的通信实战

发表评论

欢迎 访客 发表评论

一个纯粹的精品教程收录分享站点

查看演示 官网购买