⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 第20章 杂项.txt

📁 我自己整理的c语言教程 来自 c语言之家
💻 TXT
📖 第 1 页 / 共 5 页
字号:
    这里唯一的区别是"exec”变为"spawn",并且增加了模式(mode)参数。spawn()函数有覆盖和等待两种相对立的功能,它使你可以在spawn()运行期间做出是等待还是离开的决定。实现上,P_WAIT参数回答了下一个问题。

    请参见:
    20.11 怎样在一个程序执行期间运行另一个程序?

    20.11 怎样在一个程序执行期间运行另一个程序?
    正如你在20.10的例子中看到的那样,spawn()函数族允许在一个程序中启动另一个程序,并在后者结束后返回到前者之中。有关spawn()函数的背景知识和例子(你只需把其中的_P_OVERLAY改为_P_WAIT) 请参见20.10。
    然而,还有另外一种方法可以完成这项工作,即使用system()函数。system()函数与exec()或spawn()函数相似,但也不有同之处。除了挂起(而不是结束)当前程序去执行新程序外,system()还要启动COMMAND.COM命令翻译程序(或者其它任何运行在你的计算机上的命令翻译程序)。如果它找不到COMMAND.COM或类似的程序,那么它就不会去执行所要求的程序(这一点与exec()或spawn()函数不同)。下例是调用EDIT.COM打开一个文件的另一个程序版本,其中的文件名也来自该例的命令行:
# include <stdio. h>
# include <process. h>
# inclued <stdlib. h>
char argStr[255] ;
void
main(int argc, char **argv)
     int ret ;
      / * Have EDIT open a file called HELLO if no arg given * /
      sprintf (argStr ,"EDIT %s", (argv[1] == NULL?"HELLO" :argyll3) ) ;
      / * Call the one with variable arguments and an environment * /
      ret = sytem (argStr) ;
      printf("system() returned %d\n" ,ret) ;
}
    与20.10中的例子一样(使用_P_WAIT),在system()调用后面的print{()语句会被执行,因为原来的程序只是被挂起而不是被终止。在每一种情况下,system()都会返回一个表示是否成功地运行了所指定的程序的值,而不会返回所指定的程序的返回值。

    请参见:
    20.10怎样在一个程序后面运行另一个程序?

    20.12 怎样把数据从一个程序传给另一个程序?
    有好几种基本的方法可以完成这项任务----你可以通过文件或内存来传递这些数据。这些方法的步骤都相当简洁:首先,定义在何处存放数据,如何获取数据,以及如何通知另一个程序来获取或设置数据;然后,你就可以获取或设置数据了,尽管使用文件的技术定义和实现起来都比较简单,但它的速度往往比较慢(并且容易引起混乱)。因此,这里重点讨论内存数据转移技术。下面将依次详细地分析这一过程的每一个环节:
    定义在何处存放数据。当你编写要共享数据的两个程序时,你应该让程序知道要访问的数据存放在何处。这个环节同样有几种实现方法:你可以在一个(或每个)程序中建立一个固定的内部缓冲区,并在两个程序之间传递指向这个缓冲区的指针;你也可以为数据分配动态内存,并在两个程序之间传递指向该数据的指针;如果要传递的数据很小,你还可以通过CPU的通用寄存器来传递数据(这种可能性很小,因为x86结构的寄存器很少)。分配动态内存是最灵活和模块性最强的方法。
    定义获取数据的方法。这个环节非常简洁——你可以使用fmemcpy()或等价的内存拷贝函数。显然,在获取和设置数据时都可以使用这个函数。
    定义通知另一个程序的方法。因为DOS并不是一个多任务操作系统,所以其中一个(或两个)程序的一部分必须已经驻留在内存中,并且可以接受来自另一个程序的调用。同样,这个环节也有几种方法可供选择:第一个程序可以是一个列入CONFIG.SYS中的驱动程序,它在系统启动时就被装入内存;第一个程序也可以是一个TSR(终止并驻留)程序,在它退出时会把与第二个程序相互作用的那部分程序驻留在内存中;此外,你也可以在第一个程序中利用system()或spawn()函数(见20.11)来启动第二个程序。你可以根据需要选择合适的方法。因为有关DOS驱动程序的数据传递在DOS文档中已经有详尽的描述,而有关system()和spawn()函数的内容也已经在前文中介绍过,因此下面介绍TSR方法。
    下面的例子给出了两个程序:第一个程序是一个完整的TSR程序,但为了突出整个过程中的关键环节,它写得比较单薄(见20.15中的解释)。这个TSR程序先是安装了一个中断63H的中断服务程序,然后调用终止并驻留退出函数,在执行这个TSR程序后,执行下文给出的另一个程序。这个程序只是简单地初始化一个对中断63H的调用(类似于使用中断21H调用),并且把“Hello There”传送给上述TSR程序
# include <stdlib. h>
# include <dos. h>
# include <string. h>
void SetupPointers (void) ;
void OutputString(char * );
# define STACKSIZE          4096
unsigned int near OldStackPtr;
unsigned int near OldStackSeg;
unsigned int _near MyStackOff ;
unsigned int _near MyStackSeg;
unsigned char_near MyStack[STACKSIZE];
unsigned char far * MyStackPtr= (unsigned char_far * )MyStack;
unsigned short AX, BX,CX, DX,ES;
/ * My interrupt handler * /
void_interrupt_far_cdecl NewCommVector (
         unsigned short es, unsigned short ds, unsigned short di,
         unsigned short si, unsigned short bp, unsigned short sp,
         unsigned short bx, unsigned short dx, unsigned short cx,
         unsigned short ax, unsigned short ip, unsigned short cs,
         unsigned short flags) ;
/ * Pointers to the previous interrupt handier * /
void(_interrupt_far_cdecl * CommVector)();
union REGS regs;
struet SREGS segregs ;
# define COMM_VECTOR         0x63       / * Software interrupt vector * /
/ * This is where the data gets passed into the TSR * /
char_far * eallerBufPtr;
char localBuffer[255];          / * Limit of 255 bytes to transfer * /
char_far * localBufPtr=(ehar_far * )loealBuffer;
unsigned int ProgSize= 276;       / * Size of the program in paragraphs * /
void
main(int argc,char * * argv)
{
      int i, idx;
      / * Set up all far pointers * /
      SetupPointers () ;
      / * Use a cheap hack to see if the TSR is already loaded
           tf it is, exit,doing nothing * /
      comm_veetor =_dos_getvect (COMM_VECTOR) ;
      if(((long)eomm_vector & 0xFFFFL) ==
                                ((long) NewCommVector & OxFFFFL ) ) {
            OutputString("Error :TSR appears to already be loaded. \n");
            return ;
       / * If everything's set,then chain in the TSR * /
       _dos_setvect (COMM_VECTOR ,NewCommVector) ;
       / * Say we are loaded * /
       OutputString("TSR is now loaded at 0x63\n");
       / * Terminate, stay resident * /
         dos_keep (0, ProgSize ) ;
}
/ * Initializes all the pointers the program will use * /
void
Set upPointers ( )
{
     int idx ;
     / * Save segment and offset of MyStackPtr for stack switching * /
     MyStackSeg = FP_SEG (MyStackPtr) ;
     MyStackOff = FP_OFF (MyStackPtr) ;
      / * Initialize my stack to hex 55 so I can see its footprint
           if I need to do debugging * /
     for (idx = 0 ;idx<STACKSIZE ; idx ++ ) {
           MyStack [idx] = 0x55 ;
     }
}
void _interrupt_ far_cdecl NewCommVector (
            unsigned short es, unsigned short ds, unsigned short di,
            unsigned short si, unsigned short bp, unsigned short sp,
            unsigned short bx, unsigned short dx, unsigned short cx,
            unsigned short ax, unsigned short ip, unsigned short cs,
            unsigned short flags)
{
      AX = ax;
      BX = bx ;
      CX = cx;
      DX = dx ;
      ES = es ;
      / * Switch to our stack so we won't run on somebody else's * /
      _asm {
                                          ;set up a local stack
            eli                           ; stop interrupts
            mov       OldStackSeg,ss      ; save stack segment
            mov       OldStackPtr,sp      ; save stack pointer (offset)
            mov       ax,ds               ; replace with my stack s
            mov        ss,ax              ; ditto
            mov       ax,MyStackOff       ; replace with my stack s
            add       ax,STACKSIZE-2      ;add in my stack size
            mov        sp ,ax             ; ditto
            sti                           ; OK for interrupts again
     }
      switch (AX) {
            case 0x10;          / * print string found in ES:BX */
                   / * Copy data from other application locally * /
                   FP_ SEG (callerBufPtr) = ES ;
                   FP_OFF (callerBufPtr) = BX ;
                   _fstrcpy (localBufPtr, callerBufPtr ) ;
                   / * print buffer 'CX'   number of times * /
                   for(; CX>0; CX--)
                          OutputString (localBufPtr) ;
                   AX=1;             /* show success */
                   break ;
            case 0x30:               /* Unload~ stop processing interrupts * /
                   _dos_setvect (COMM_VECTOR ,comm_vector) ;
                   AX=2;                   /* show success */
                   break ;
             default :
                   OutputString (" Unknown command\r\n" ) ;
                   AX= 0xFFFF;                / * unknown command-1 * /
                   break ;
     }
      / * Switch back to the caller's stack * /
        asm {
             cli                               ;turn off interrupts
             mov       ss,OldStackSeg    ;reset old stack segment
             mov        sp,OldStackPtr ;reset old stack pointer
             sti                             ;back on again
     }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -