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。