2012年4月9日
#
一个机器上的两个进程间通信,可以使用很多种方式。但看《windows核心编程》说,其实归根结底都是使用了file-mapping kernel object。把那一章看了看,长了不少知识。但是我最感兴趣的地方还是:假设有两个线程:线程A和线程B。当线程A在运行的时候,线程B给A通信,使得A可以改变自己程序的运行轨迹。其实,这也算是为调试程序埋的伏笔吧。因为我现在的工作中就遇到一个这样的问题,程序A可以运行,但运行效果不是想要的,我想使用程序B给A发一些消息,改变A的运行轨迹。在VS2008的msdn文档中找了找,找到一个简单的例子,修改了一下。代码包括两部分,第一部分是程序A的代码,代码如下:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject");
int main()
{
HANDLE hMapFile;
char * pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // max. object size
BUF_SIZE, // buffer size
szName); // name of mapping object
if (hMapFile == NULL)
{
printf("Could not create file mapping object (%d).\n",
GetLastError());
return 1;
}
pBuf = (char *) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
printf("Could not map view of file (%d).\n",
GetLastError());
return 2;
}
while (1)
{
if (*pBuf == 'a')
{
printf("hello world!\n");
}
else
{
printf("no hello\n");
}
Sleep(2000);
}
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
return 0;
}
第二部分是程序B的代码,代码如下:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject");
int main()
{
HANDLE hMapFile;
char * pBuf;
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szName); // name of mapping object
if (hMapFile == NULL)
{
printf("Could not open file mapping object (%d).\n",
GetLastError());
return 1;
}
pBuf = (char *) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
printf("Could not map view of file (%d).\n",
GetLastError());
return 2;
}
printf("press a key!\n");
_getch();
*pBuf = 'a';
printf("press another key!\n");
_getch();
*pBuf = 'b';
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
return 0;
}
平时的时候,程序A正常运行,每隔两秒打印一次“no hello”,启动程序B后,如果按下回车,则程序A会不断打印“hello world”,程序B中再次按回车,程序A又回到原来的运行轨迹,不断打印“no hello”。这样,通过file-mapping kernel object的方式,实现了进程间的通信。
至于文件映射内核对象的原理之类的话,我就不多说了,使用google搜索,一搜一大把。大家也可以看书,《windows核心编程》讲的很好。
其实,上面这个例子,我感觉挺傻的。不过现在没想到多么好的办法,可以使进程B通过通信的方式影响进程A的运行轨迹。 先把这种笨方法记录下来,等找到好的办法,再写上来,哈哈。
网上还有好多不错的文章,贴出几个来:
http://blog.codingnow.com/2005/10/interprocess_communications.html
http://learn.akae.cn/media/ch30s04.html
2011年11月15日
#
2011年11月14日
#
2011年9月17日
#
2011年9月13日
#
在DOS的批处理中,有时候需要知道当前的路径。在DOS中,有两个环境变量可以跟当前路径有关,一个是%cd%, 一个是%~dp0。
这两个变量的用法和代表的内容一般是不同的。
1. %cd% 可以用在批处理文件中,也可以用在命令行中;展开后,是驱动器盘符:+当前目录,如在dos窗口中进入c:\dir目录下面,
输入:echo %cd% ,则显示为:c:\dir 。
%cd%的时间内容是可以被改变的,比如CD命令就可以改变它的内容。
2.%~dp0只可以用在批处理文件中,它是由它所在的批处理文件的目录位置决定的,是批处理文件所在的盘符:+路径。在执行这个批处理文件的过程中,它展开后的内容是不可以改变的。比如在D盘下有个批处理文件,dirshow.bat,其内容为
@echo off
echo this is %%cd%% %cd%
echo this is %%~dp0 %~dp0 在C:\ 下执行它,输出为:
C:\>D:\dirshow.bat
this is %cd% C:\
this is %~dp0 D:\