Top: Table of contents
Next: Appendix C. Using gnuplot commands in shell script
Previous: Appendix A. The initial setting of GNUPLOT

Appendix B. Call gnuplot from C program

我们可在 C 程式中呼叫 gnuplot 替我们绘图。方法为产生 process 执行 gnuplot,建立对 gnuplot 下达命令的管道,使用档案传递资料。以下是在 UNIX 中呼叫 gnuplot 的例子:(程式码可由此获得)

    1   #include <sys/types.h>
    2   #include <sys/stat.h>
    3   #include <stdlib.h>
    4   #include <stdio.h>
    5   #include <math.h>
    6   #include <unistd.h>
    7   
    8   #define PANIC(a) do { \
    9                   perror(a); \
   10                   if (temp_name) unlink(temp_name);\
   11                   exit(1);\
   12           } while(0)
   13   
   14   int main() {
   15       FILE *command,*data;
   16       char *temp_name;
   17       double a,b;
   18       int i;
   19   
   20       if ((temp_name = tmpnam((char *) 0)) == 0) PANIC("tmpnam failed");
   21       if(mkfifo(temp_name, S_IRUSR | S_IWUSR) != 0) PANIC("mkfifo failed");
   22       command = popen("gnuplot","w");
   23       fprintf(command,"plot \"%s\" with lines\n",temp_name); fflush(command);
   24       data = fopen(temp_name,"w");
   25       for (i=0; i<20; i++) {
   26           a = i/10.0;
   27           b = sin(a);
   28           fprintf(data,"%f %f\n",a,b);
   29       }
   30       fclose(data);
   31       fprintf(stderr,"press enter to continue..."); fflush(stderr);
   32       getchar();
   33   
   34       fprintf(command,"plot \"%s\" with lines\n",temp_name); fflush(command);
   35       data = fopen(temp_name,"w");
   36       for (i=0; i<20; i++) {
   37           a = i/10.0;
   38           b = cos(a);
   39           fprintf(data,"%f %f\n",a,b);
   40       }
   41       fclose(data);
   42       fprintf(stderr,"press enter to continue..."); fflush(stderr);
   43       getchar();
   44       fclose(command);
   45       unlink(temp_name);
   46       return 0;
   47   }

程式在第 22 行使用函数 popen() 执行 gnuplot 并建立对 gnuplot 下命令的通道。 ( 关于函数 popen() 的说明,可参考 W. Richard Stevens, Advanced Programming in the UNIX Environment. Addison-Wesley, pp 435-441, 1992.) 程式在 23 行使用

 
   fprintf(command,"plot \"%s\" with lines\n",temp_name);
   fflush(command);

下达命令给 gnuplot。在 21 行使用函数 mkfifo() 建立储存资料的档案。 ( 关于函数 mkfifo() 的说明,可参考 W. Richard Stevens, Advanced Programming in the UNIX Environment. Addison-Wesley, pp 445-449, 1992. ) 由第 35 至 40 行程式

 
   data = fopen(temp_name,"w");
   for (i=0; i<20; i++) {
       a = i/10.0;
       b = cos(a);
       fprintf(data,"%f %f\n",a,b);
   }

可在档案中产生一组描述数学三角函数 cos(x) 的数值资料。因此程式可对 gnuplot 下命令并将数值资料准备在档案内,再由 gnuplot 读取。

下面是 OS/2 中 C 程式呼叫 gnuplot 的例子 (使用 GCC compilier): (程式码可由此获得)

    1   #include <stdio.h>
    2   #define INCL_DOS
    3   #define INCL_DOSPROCESS
    4   #define INCL_DOSNMPIPES
    5   #include <os2.h>
    6   
    7   main()
    8       {
    9       HPIPE hpipe ;
   10       FILE *hfile, *hgnu ;
   11           /* create a named pipe. Use NP_WAIT so that DosConnect...
   12              blocks until client (gnuplot) opens, and client reads
   13              are blocked until data is available */
   14       DosCreateNPipe( "\\pipe\\gtemp",
   15                       &hpipe,
   16                       NP_ACCESS_OUTBOUND,
   17                       NP_WAIT|NP_TYPE_BYTE|1,
   18                       256,
   19                       256,
   20                       -1 ) ;
   21           /* use stream i/o */
   22       hfile = fdopen( hpipe, "w" ) ;
   23   
   24           /* start gnuplot; use unbuffered writes so we don't need to
   25              flush buffer after a command */
   26       hgnu = popen( "gnuplot", "w" ) ;
   27       setvbuf( hgnu, NULL, _IONBF, 0 ) ;
   28   
   29           /* plot a set of data */
   30   
   31       fprintf( hgnu, "plot '/pipe/gtemp'\n" ) ;  /* issue plot command */
   32       DosConnectNPipe( hpipe ) ;              /* wait until 'file' opened */
   33       fprintf( hfile, "1 1\n" ) ;             /* write data to 'file' */
   34       fprintf( hfile, "2 2\n" ) ;
   35       fprintf( hfile, "3 3\n" ) ;
   36       fprintf( hfile, "4 4\n" ) ;
   37       fflush( hfile ) ;                       /* flush buffer forces read */
   38       DosSleep( 500 ) ;
   39       DosDisConnectNPipe( hpipe ) ;           /* disconnect this session */
   40       fprintf( hgnu, "pause -1\n" ) ;         /* admire plot */
   41   
   42           /* plot another set of data */
   43   
   44       fprintf( hgnu, "plot '/pipe/gtemp'\n" ) ;
   45       DosConnectNPipe( hpipe ) ;
   46       fprintf( hfile, "1 4\n" ) ;
   47       fprintf( hfile, "2 3\n" ) ;
   48       fprintf( hfile, "3 2\n" ) ;
   49       fprintf( hfile, "4 1\n" ) ;
   50       fflush( hfile ) ;
   51       DosSleep( 500 ) ;
   52       DosDisConnectNPipe( hpipe ) ;
   53       fprintf( hgnu, "pause -1\n" ) ;
   54   
   55       DosClose( hpipe ) ;
   56       pclose( hgnu ) ;
   57       }


Top: Table of contents Next: Appendix C. Using gnuplot commands in shell script