我的CMD工程(1) 请指点

本文介绍了一种自定义指令系统的实现思路,通过DLL加载及函数调用来解析和执行用户自定义命令,支持参数传递和类型转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很早以前就打算写一个自己的CMD,CMD,就类似与C:/WINDOWS/system32/CMD.exe的东东,就是输入一些指令代码,它就会完成相应的功能。比如敲入dir,则列出当前目录下的文件和文件夹等。

     一个好的CMD(你可以叫它为指令解析系统)能够允许用户自定义指令,然而你也许不想让用户看到你的代码,这可以用dll来实现,用户按照你的编写规则,创建自己的一个dll,这个dll里面是用户自己定义的命令,相应的又一些命令函数,然后在一个规定的文件(比如FunctionInfo.txt)中加入一些dll信息和指令信息,而你的CMD系统可以根据这个文件来查找相应的dll并调用相应的命令函数。

    还有一个困难,就是如何根据用户输入的命令来进行解析,并调用相应的命令函数呢?这便是CMD核心的东西,在此之前,你应该了解一下dll。一个exe可以利用一个dll中的函数名来调用该函数,也可以利用该函数在dll中的编号来调用它。

    例如:GetProcAddress(hDll,MAKEINTRESOURCE(num));

该函数返回编号为num的函数的地址,其中的hDll可以用hDll = LoadLibrary(dllname);来获取,dllname就是dll的文件名,可以在FunctionInfo.txt中给出。于是就可以定位该命令函数了。

    也许你会问命令函数是什么东东,呵呵,一个CMD就是利用输入的指令,根据指令来调用相应的函数以完成一定的功能,这个和命令相关联的函数就是命令函数了。^-^

    有一些命令是有参数的,比如计算加分的命令,我们这里以add命令为例,来编写add命令。应该完成这样的功能,用户输入add 34 56(按回车)CMD要对输入的这个命令进行分解,分解成命令名和参数,显然,这里的add是命令名,34 56为两个参数,CMD系统在进行处理,把输入的34 56存放在string里面,然后对其进行参数压栈,压栈顺序是从右向左。所以系统中应该还要有个参数栈,学过了数据结构,这个栈会很容易实现。参数压栈完还要再对命令add进行处理,因为要定位相应的命令函数。由于GetProcAddress()是返回参数的地址,也就是函数的指针,

typedef void (_stdcall *lpFun) ();//定义函数指针

我们这样来定义一个参数为空,返回值为void的函数指针,我们不可能定义很多很多的指针函数,于是我们规定,所以的命令函数都应该满足参数为空,返回值为void的要求。你会问,可是add 34 56 命令里有两个参数呀!没错,因为我们已经对参数压栈了,我们只要进行出栈操作就可以了。

对add进行处理,就是要找到add命令的命令函数位于哪个dll里面,并且在dll中的编号是什么,这都记录在FunctionInfo.txt里面,FunctionInfo.txt的编写格式是这样的,每一行是一个命令记录,其从左向右的属性分别为:

命令标号| |函数名|    |函数所在DLL|    |函数参数| |在DLL中的序号|
属性之间用空格隔开。

例如:

1   acos      Math.dll  5   1
2   add       Math.dll  55  2
3   asin      Math.dll  5   3

。。。。

29  listprocess     Control.dll   0   8
30  closeprocess  Control.dll   0   1
31  listwindow     Control.dll   0    9
32  closewindow  Control.dll   0    2

函数参数的标号这样规定:
0代表没有参数
1代表char*
2代表char
3代表int
4代表float
5代表double
6代表string
...
于是根据输入的add来进行查找,查找记录的第二个属性,于是查找到记录为:
2   add       Math.dll  55  2
的行,再对该行进行处理,获得add命令所在的dll文件名,为Math.dll,参数类型为55(即两个double类型的参数,并获得add的命令函数在Math.dll中的编号为2,于是,我们就可以进行定位该函数了。
可问题又出来了,你要的参数是double可参数栈中的类型为string啊,这也好办,CMD中要有一个专门处理参数类型的方法,可以根据参数类型如:55,来进行参数的处理,处理后放在参数结构体里面:参数结构体是这样的:
struct realparm
{
char char_parm[16];
int int_parm[16];
float float_parm[16];
double double_parm[16];
char str_parm[16][64];
string string_parm[16];
};
于是add的函数编写就是这样的:
void _stdcall add()
{    
 cout<<parm->double_parm[0]+parm->double_parm[1]<<endl;
}
其中的parm是指向realparm类型的指针,为公共指针。
于是改命令就被成功解析了,调用了add()函数,输出90

然而这只是简单的命令解析和命令函数调用,本CMD中还有很多其他的解析和调用方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值