zoukankan      html  css  js  c++  java
  • complier pgplot program using c language==Calling PGPLOT from a C Program

    from:http://pulsar.ca.astro.it/pulsar/Docs/pgplot/cbinding.html Calling PGPLOT from a C Program

    C.1 Introduction

    PGPLOT is a Fortran subroutine library, and calling Fortran subroutines directly from C is a messy, difficult, and unportable exercise. This is due to the lack of a universal set of interlanguage calling conventions, and to the lack of a standard on how FORTRAN LOGICAL and CHARACTER types are represented in terms of basic machine types. Furthermore, since C implements call-by-value argument passing semantics, whereas FORTRAN uses pass-by-reference, there is the added complication that literal values must be sent indirectly by way of references to dummy variables. The CPGPLOT library adds an intermediate level of wrapper functions between C programs and the PGPLOT library. These functions hide the system dependencies of calling PGPLOT behind a system-independent interface. It is essential when using the CPGPLOT interface library to include the library header file cpgplot.h at the top of all C files containing calls to the library. Without this file, the functions will not be correctly prototyped and your code will not work. The CPGPLOT library can be used only with an ANSI-compatible C compiler that understands C function prototypes.

    C.2 Using the CPGPLOT library

    The names of the C interface library functions are the same as their PGPLOT counterparts, but are prefixed with a c and written in lower case, e.g., PGTEXT becomes cpgtext. The header file cpgplot.h declares the types of the arguments of each CPGPLOT routine. The types can usually be deduced from the FORTRAN subroutine descriptions in Appendix A, as described below, but cpgplot.h should be consulted in case of doubt.

    REAL and INTEGER arguments

    Where the PGPLOT routine expects a REAL or INTEGER argument, supply the C routine with a float or int argument as appropriate. If the Fortran routine uses the argument for input only, it should be passed by value; but if it is used to return a value, supply a pointer to a variable of the appropriate type. If the FORTRAN argument is an array, the C argument should be a pointer to an array. For two-dimensional arrays, supply a pointer to a one-dimensional C array in which the elements are packed with the first index changing fastest (see example below).

    LOGICAL arguments

    Where the PGPLOT routine expects a LOGICAL argument, the C routine requires an int argument. Zero is interpreted as FORTRAN .FALSE. and non-zero as FORTRAN .TRUE., e.g.,
        FORTRAN call.       C equivalent call(s).
        --------------      ----------------------------
        PGASK(.FALSE.)      cpgask(0)
        PGASK(.TRUE.)       cpgask(1) or cpgask(2) etc..

    CHARACTER arguments

    When the FORTRAN routine expects a CHARACTER argument for input, the C routine takes a normal C pointer to a nul-terminated string (char array, with end-of string marked by '\0'). Arguments that are used to return FORTRAN character strings must be treated with care. FORTRAN doesn't understand '\0' termination of strings and instead requires that the dimension of the character array be specified along with the array. The interface handles this transparently for input-only strings by using strlen() to determine the length of the string, but for return string arguments it needs to be told the length available in the passed char array. Fortunately all PGPLOT routines that return such strings also have an argument to return the unpadded length of the return string. In CPGPLOT, you must initialize this argument with the dimension of the string array that has been sent. In the prototypes listed in cpgplot.h the length arguments are distinguishable by virtue of their having the name of the string to which they relate, postfixed with _length. For example, the PGPLOT routine PGQINF() is prototyped as
         void cpgqinf(char *item, char *value, int *value_length);
    where the value_length argument is the length argument for the string argument value. For example, to write a C function to return 1 if a PGPLOT device is open, or 0 otherwise, one could write.
         #include "cpgplot.h"
         int pgplot_is_open(void)
         {
           char answer[10];                 /* The PGQINF return string */
           int answer_len = sizeof(answer); /* allocated size of answer[] */
           cpgqinf("STATE", answer, &answer_len);
           return strcmp(answer, "YES") == 0;
         }
    Note that the dimension, sent as the third argument, is the total number of characters allocated to the answer[] array. The interface function actually subtracts one from this when it tells PGPLOT how long the string is. This leaves room for the interface function to terminate the returned string with a '\0'. All returned strings are terminated in this manner at the length returned by PGPLOT in the length argument.

    C.3 Limitations

    PGPLOT procedures that take FORTRAN SUBROUTINEs or FUNCTIONs as arguments (e.g., PGFUNX, PGCONX) are not represented in the CPGPLOT library. Such procedures cannot be handled on most systems.

    C.4 Other Machine Dependencies

    Many system vendors say that if you call FORTRAN functions that do any I/O, you should have a FORTRAN main program, so that the FORTRAN I/O module gets correctly initialized. Since PGPLOT uses FORTRAN I/O, this applies to C programs that call PGPLOT. Since FORTRAN usually has to be linked with a lot of support libraries, it is usually most convenient to use the FORTRAN compiler to link your C program. If your compiler is not the system-supplied compiler, then it is unlikely that the FORTRAN compiler will cite the correct C run-time library to the linker. This means that you will have to do it yourself (e.g., the gcc compiler requires programs to be linked with libgcc.a, e.g.,
     gcc -c blob.c
     f77 -o blob blob.o -lcpgplot -lpgplot -lX11 -lgcc -lm

    Example: Solaris

    Replace /usr/local/pgplot with your PGPLOT directory.
    cc -c -I/usr/local/pgplot ctest.c
    f77 -o ctest ctest.o -L/usr/local/pgplot -lcpgplot -lpgplot

    C.5 Examples

    The following example shows some simple CPGPLOT calls:
    #include "cpgplot.h"
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int main()
    {
      int i;
      static float xs[] = {1.0, 2.0, 3.0, 4.0, 5.0 };
      static float ys[] = {1.0, 4.0, 9.0, 16.0, 25.0 };
      float xr[60], yr[60];
      int n = sizeof(xr) / sizeof(xr[0]);
      /*
       * Call PGBEG to initiate PGPLOT and open the output device; PGBEG
       * will prompt the user to supply the device name and type.
       */
      if(cpgbeg(0, "?", 1, 1) != 1)
        return EXIT_FAILURE;
      /*
       * Call PGENV to specify the range of the axes and to draw a box, and
       * PGLAB to label it. The x-axis runs from 0 to 10, and y from 0 to 20.
       */
      cpgenv(0.0, 10.0, 0.0, 20.0, 0, 1);
      cpglab("(x)", "(y)", "PGPLOT Example 1: y = x\\u2\\d");
      /*
       * Mark five points (coordinates in arrays XS and YS), using symbol
       * number 9.
       */
      cpgpt(5, xs, ys, 9);
      /*
       * Compute the function at 'n=60' points, and use PGLINE to draw it.
       */
      for(i=0; i<n; i++) {
        xr[i] = 0.1*i;
        yr[i] = xr[i]*xr[i];
      }
      cpgline(n, xr, yr);
      /*
       * Finally, call PGEND to terminate things properly.
       */
      cpgend();
      return EXIT_SUCCESS;
    }
    A second example shows how a two-dimensional FORTRAN array should be handled:
    #include "cpgplot.h"
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int main()
    {
      static int nx = 40, ny = 40;
      int i, j, k, lw, ci, ls;
      float f[1600], fmin, fmax, alev;
      double x, y;
      static float tr[6] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
    
      printf("Demonstration of PGPLOT contouring routines\n");
    
      /* Compute a suitable function. A C array is used to emulate
         a 2D fortran array f(nx,ny). */
    
      fmin = fmax = 0.0;
      for (j=1; j<=ny; j++) {
        for (i=1; i<=ny; i++) {
          k = (j-1)*nx + (i-1);	/* Fortran convention */
          x = tr[0] + tr[1]*i + tr[2]*j;
          y = tr[3] + tr[4]*i + tr[5]*j;
          f[k] = cos(0.3*sqrt(x*2)-0.13333*y)*cos(0.13333*x)+
    	(x-y)/(double)nx;
          if (f[k] < fmin) fmin = f[k];
          if (f[k] > fmax) fmax = f[k];
        }
      }
    
      /* Call PGBEG to initiate PGPLOT and open the output device; PGBEG
       * will prompt the user to supply the device name and type. */
    
      if(cpgbeg(0, "?", 1, 1) != 1)
        return EXIT_FAILURE;
    
      /* Clear the screen. Set up window and viewport. */
    
      cpgpage();
      cpgsvp(0.05, 0.95, 0.05, 0.95);
      cpgswin(1.0, (float) nx, 1.0, (float) ny);
      cpgbox("bcts", 0.0, 0, "bcts", 0.0, 0);
      cpgmtxt("t", 1.0, 0.0, 0.0, "Contouring using PGCONT");
    
      /* Draw the map.  PGCONT is called once for each contour, using
         different line attributes to distinguish contour levels. */
    
      cpgbbuf();
      for (i=1; i<21; i++) {
        alev = fmin + i*(fmax-fmin)/20.0;
        lw = (i%5 == 0) ? 3 : 1;
        ci = (i < 10)   ? 2 : 3;
        ls = (i < 10)   ? 2 : 1;
        cpgslw(lw);
        cpgsci(ci);
        cpgsls(ls);
        cpgcont(f, nx, ny, 1, nx, 1, ny, &alev, -1, tr);
      }
      cpgslw(1);
      cpgsls(1);
      cpgsci(1);
      cpgebuf();
      /*
       * Finally, call PGEND to terminate things properly.
       */
      cpgend();
      return EXIT_SUCCESS;
    }
     
  • 相关阅读:
    iOS 十六进制字符串 "#FFFF00" 转换成颜色对象
    iOS toast 的连续显示
    文件管理
    pod 常用命令
    键盘事件
    iOS 添加阴影
    渐变色
    Ubuntu安装flameshot截图工具
    Ubuntu安装酸酸乳客户端
    Ubuntu安装网易云音乐
  • 原文地址:https://www.cnblogs.com/shaoguangleo/p/2806064.html
Copyright © 2011-2022 走看看