NAG DLL 算法库与 Microsoft C ++

大部分的系统都允许 C 程序去调用其他的语言函数。事实上在 ANSI 定义的 C 语言标准中,提供了功能强大的参数验证功能,能够方便在 C 与各种语言 (例如 Fortran) 间的跨语言沟通。

NAG Fortran DLL 档可以在 C 或 C++ 环境中调用使用。为方便用户在 Fortran 与 C 语言间的型别对应,我们提供了 C Header 档,能让 C 编译器进行参数验证。 相关的头文件可在 NAG Fortran 算法库中找到。

若用户想要使用 Fortran DLL 的函数,我们建议您在 C 程序中直接剪贴相关的定义片段。或者,NAG C Header 文件在 Headers 目录中也有提供,请参考目录中的 techdoc.html 说明,了解如何使用 C 头文件。 请参考 在 C 语言中如何使用 NAG C Header 文件调用 NAG Fortran 函数

Fortran 与 C 语言基本上对于传递参数是以不同的方式进行的。然而在任何混合编程的程序设计中,调用的协议便需要一致。 因此,Visual C++ 的使用者必须要指定 STDCALL 调用协议。可以透过明确指定 __stdcall 关键词的方式调用 NAG 函数,或者是在 Microsoft Developer Studio 中设定链接的调用协议。

另外还有一些 C 与 Fortran 语言不同的地方。例如:Fortran 函数中的数组是以 1 为开头,而 C 语言的协议是以 0 为开头。同样的,也必须注意二维数组: Fortran 语言的协议,数组元素 (1,1) 的下一个物理内存的元素是 (2,1);而 C 语言则为 (1,2)。(也就是说,Fortran 是以列方式储存,而 C 语言是以行方式储存)。 也因此对于 C 程序来说,就必须要就必须要将数组进行转换后才能调用 Fortran 的函数。

C 语言与 Fortran 语言的字符串处理是不同的。在 Compaq Visual Fortran 中传递字符串参数是以 4 位方式 passed by value 传递,并接着字符串长度。

以下的两个示例,说明如何在 Microsoft Visual C++ 环境调用 NAG DLL。

示例 1:说明矩阵与字符串处理方式

#include <stdio.h>
  #define CONST const
typedef struct { char *str; int val; } Fortran_character_arg;

  extern void __stdcall F01QCF(
    CONST int *m,
    CONST int *n,
    double a[ ],
    CONST int *lda,
    double zeta[ ],
    int *ifail
  );

  extern void __stdcall F01QDF(
    CONST Fortran_character_arg trans,
    CONST Fortran_character_arg wheret,
    CONST int *m,
    CONST int *n,
    double a[ ],
    CONST int *lda,
    CONST double zeta[ ],
    CONST int *ncolb,
    double b[ ],
    CONST int *ldb,
    double work[ ],
    int *ifail
  );

  /* Simplified example program for F01QDF */

  main( )
  {
    int i,ifail,j,m = 5,n = 3,ncolb = 2;
    int lda = m,ldb = m;
    Fortran_character_arg tr = {"Transpose",9};
    Fortran_character_arg se = {"Separate",8};
    /* Initialise arrays in column major order */
    static double a[3][5] =
      {
        2.0, 2.0, 1.6, 2.0, 1.2,
        2.5, 2.5, -0.4, -0.5, -0.3,
        2.5, 2.5, 2.8, 0.5, -2.9
      };
    static double b[2][5] =
      {
        1.1, 0.9, 0.6, 0.0, -0.8,
        0.0, 0.0, 1.32, 1.1, -0.26
      };
    double work[2],zeta[3];

    printf("F01QDF Example Program Results\n\n");
    ifail = 0;
    F01QCF(&m,&n,(double *)a,&lda,zeta,&ifail);
    ifail = 0;
    F01QDF(tr,se,&m,&n,(double *)a,&lda,zeta,&ncolb,(double
  *)b,&ldb,work,&ifail);
    printf("Matrix  Q'*B\n");
    for (i=0; i<m; i++)
      {
        for (j=0; j<ncolb; j++)
          {
            printf("%f ",b[j][i]);
          }
        printf("\n");
      }
    return 0;
  }

示例 2:说明如何调用函数

#include <math.h>
  #include <stdio.h>
  #define CONST const
  typedef struct { char *str; int val; } Fortran_character_arg;
  extern void __stdcall C05AJF(
    double *x,
    CONST double *eps,
    CONST double *eta,
    double (__stdcall *f)(double *),
    CONST int *nfmax,
    int *ifail
  );

  static double __stdcall f(double *);

  main( )
  {
    double eps, eta, x;
    int ifail, k, nfmax;

    printf("C05AJF Example Program Results\n\n");
    for (k=1; k<=2; k++)
      {
        eps = k==1 ? 0.1e-3 : 0.1e-4;
        x = 1.0;
        eta = 0.0;
        nfmax = 200;
        ifail = 1;
        C05AJF(&x,&eps,&eta,f,&nfmax,&ifail);
        if (ifail==0)
          printf("With eps = %e   root = %f\n",eps,x);
        else
          {
            printf("ifail = %d\n",ifail);
            if (ifail==3 | ifail==4)
              printf("With eps = %e final value = %f\n",eps,x);
          }
      }
    return 0;
  }
  static double __stdcall f(double *x)
  {
    return exp(-*x) - *x;
  }

这两个示例程序都能在 Microsoft Developer Studio 环境中正确的执行。唯一要注意的地方是,您需要将调用协议改为 STDCALL 方式。

您可以参考更多有关讯息 在 C 语言中使用 NAG C 头文件调用 NAG Fortran 函数

此外,NAG C 算法库也提供超过 1,300 多个函数。如同其他的 NAG 产品,您也可以获得相同质量的函数。您可以参考更多讯息:使用 C 算法库 DLL