未定义对'的引用;d1马赫'; 我试图把Fortran子程序与C++连接起来,但不能确切地理解这里到底有什么错误: fortran子例程调用一些函数,例如d1mach或xermsg,这些函数没有在fortran子例程中定义,而是在外部调用。编译时,错误为“未定义对d1mach_3;的引用”(或xermsg)。 我尝试链接一个我认为可能包含上述函数的库(库中似乎有一个名为d1mach.o和xermsg.o的文件),但同样的错误仍然存在。我可能做错了什么 extern"C" { void drc3jm_(double *L1,double *L2,double *L3,double *M1,double *M2MIN, double *M2MAX,double *THRCOF,int *NDIM,int *IER); }

未定义对'的引用;d1马赫'; 我试图把Fortran子程序与C++连接起来,但不能确切地理解这里到底有什么错误: fortran子例程调用一些函数,例如d1mach或xermsg,这些函数没有在fortran子例程中定义,而是在外部调用。编译时,错误为“未定义对d1mach_3;的引用”(或xermsg)。 我尝试链接一个我认为可能包含上述函数的库(库中似乎有一个名为d1mach.o和xermsg.o的文件),但同样的错误仍然存在。我可能做错了什么 extern"C" { void drc3jm_(double *L1,double *L2,double *L3,double *M1,double *M2MIN, double *M2MAX,double *THRCOF,int *NDIM,int *IER); },c++,c,fortran,gfortran,C++,C,Fortran,Gfortran,这是我用来调用子例程的函数,在iostream旁边没有使用任何新的头 *DECK DRC3JM SUBROUTINE DRC3JM (L1, L2, L3, M1, M2MIN, M2MAX, THRCOF, NDIM, + IER) CALL XERMSG('SLATEC','DRC3JM','L1-ABS(M1) less than zero or '// + 'L1+ABS(M1) not integer.',IER,1) 这是调用未声明函数

这是我用来调用子例程的函数,在iostream旁边没有使用任何新的头

*DECK DRC3JM
      SUBROUTINE DRC3JM (L1, L2, L3, M1, M2MIN, M2MAX, THRCOF, NDIM,
     +   IER)
CALL XERMSG('SLATEC','DRC3JM','L1-ABS(M1) less than zero or '//
     +      'L1+ABS(M1) not integer.',IER,1)
这是调用未声明函数xermsg的fortran子例程的声明

我使用-L/path/lib指令链接库,但没有效果。 子程序用于计算数学函数,是slatec代码的一部分


请告诉我您可能需要的其他信息。

问题持续存在的原因可能只是因为您的
lib3j6j9j.a
不包含必要的文件(如d1mach)。实际上,我们可以相当直接地编译必要的文件,因此我将总结以下过程:

1) 从Netlib/Slatec页面(或)下载
drc3jm.f
(计算3j符号)和依赖项。解压缩存档文件以获取Fortran文件(*.f)

2) 移除
d1mach.f
i1mach.f
r1mach.f
(如果有)。相反,请从Netlib/blas(*)下载其替代版本:

3) 编译所有*.f文件

gfortran testf.f90 *.f
连同主程序testf.f90(自由格式),例如

然后运行可执行文件会得到所需的结果


3-a)我们也可以将这些*.f作为库,并与C++代码链接,例如:

gfortran -c *.f
ar rv mylib.a *.o
g++ testc.cpp mylib.a -lgfortran
使用主程序(testc.cpp)

您也可以使用在线工具获得相同的结果,例如


但根据具体情况,使用其他库可能更简单。一种方法是将相应的GSL例程()用作

#包括
外部“C”
双gsl_sf_联轴器_3j(int two_ja,int two_jb,int two_jc,
int-two-ma,int-two-mb,int-two-mc);
int main()
{
双系数;
coef=gsl_sf_联轴器_3j(30,60,80,4,4,-8);/-0.019081579799205
//注:所有j和m需要加倍。
printf(“coef=%20.15f\n”,coef);
返回0;
}
这里您需要链接必要的GSL库(例如,
g++test.cpp-lgsl
g++test.cpp/usr/lib64/libgsl.so.0/usr/lib64/libgslcblas.so.0
等)


另一种方法是使用最新的程序(相关论文为)。我尝试了一下,它似乎非常容易安装和使用(只有一个
make
)。例如,输入
example/
目录并尝试
gcc-I../inc csimple.c../lib/libwigxjpf.a
。 根据上面的文章,这个程序可以提供一些准确性和性能优势



(*)有关更多详细信息,请参阅(感谢评论中的@VladimirF)。我们可以在Slatec中使用原始的d1mach.f等,但我们需要修改它们以获得正确的机器相关常数。上述BLAS版本的d1mach.f etc会自动处理此问题,因此更方便

您需要链接到Fortran运行时库。尝试将-lgfortran添加到链接中command@antlersoft我已经这样做了,我为这两个文件创建了.o文件,然后使用-lgfortran和-L指令编译它们。无论是否使用-L指令,这都会导致此错误。您可以共享用于编译和链接的完整命令行吗?@Smeeheey我使用了以下指令:gfortran-c drc3jm.f g++-c test.cpp g++test drc3jm.o test.o-lgfortran-L/usr/3j6j9j您尝试过UTFG吗?“r1mach、d1mach和i1mach是什么,在哪里?”他们来自布拉斯。对于
xermsg
,这又是来自网络搜索的第一个链接。哇,这是惊人的详细!我几乎放弃了希望。非常感谢@roygvib!我还没有达到第二步,但它似乎是一个解决方案,以南的价值观,我得到。将在早上更新进度。这非常有效!第二种方法正是我想要的(C++连接的一种方法。不下载D1MACH的替代版本,问题是它给了我-结果。下载替代版本似乎已经解决了这个问题)。感谢您提供了一个非常详细和白痴证明答案!事实上,这是我第一次使用BLAS版本的d1mach.f等,结果证明非常有用。(因为我不知道,我需要手动修改它们来运行一些AMOS代码,请看这个…所以更新了它。)至于NaN,我想这是因为旧版本的d1mach.f给出了0.0作为“巨大”值(除非我们取消注释必要的行)。无论如何,很高兴知道有一个简单的解决办法:)干杯
gfortran testf.f90 *.f
program main
implicit none
integer, parameter :: N = 1000
double precision coef( N ), M2min, M2max, M2
integer ier
ier = 0 ; coef(:) = 0.0d0

call DRC3JM( 15.0d0, 30.0d0, 40.d0, 2.0d0,  M2min, M2max, coef, N, ier )
print *, "M2min, M2max, ier = ", M2min, M2max, ier

M2 = 2.0d0
print "(a, f20.15)", "coef = ", coef( nint(M2 - M2min+1) )  !! -0.019081579799192
end
gfortran -c *.f
ar rv mylib.a *.o
g++ testc.cpp mylib.a -lgfortran
#include <cstdio>
extern "C"
double drc3jm_ (double*, double*, double*, 
                double*, double*, double*, double*, int*, int*);

int main()
{
    double* coef;
    double L1, L2, L3, M1, M2min, M2max, M2;
    int ier, k, N = 1000;

    coef = new double [ N ];
    L1 = 15.0; L2 = 30.0; L3 = 40.0; M1 = 2.0;

    drc3jm_ ( &L1, &L2,    &L3,
              &M1, &M2min, &M2max, coef, &N, &ier );  
    printf( "M2min, M2max, ierr = %10.5f%10.5f%d\n", M2min, M2max, ier );

    M2 = 2.0;   
    k = (int)(M2 - M2min + 1.0e-3);
    printf( "coef = %20.15f\n", coef[ k ] );  // -0.019081579799192
    return 0;
}
j1=15, j2=30, j3=40, m1=2, m2=2, m3=-4
#include <cstdio>
extern "C"
double gsl_sf_coupling_3j (int two_ja, int two_jb, int two_jc,
                           int two_ma, int two_mb, int two_mc);  
int main()
{
    double coef;
    coef = gsl_sf_coupling_3j( 30, 60, 80, 4, 4, -8 );  // -0.019081579799205
    // NOTE: all j's and m's need to be doubled.

    printf( "coef = %20.15f\n", coef );
    return 0;
}