我有这个fortran 90文件(将代码添加到问题的底部),我已使用以下命令将其编译到OS X Mavericks上的动态库中:gfortran -dynamiclib trianglepy.f90 -o libtriangle.dylib。这将产生libtriangle.dylib,该文件存储在我的桌面上。然后,我可以使用该库(位于底部的代码)制作C ++文件。我比使用g++ main.cpp -o main -std=c++11 -L ~/Desktop/ -ltriangle编译代码。这样可以完美地编译代码。但是,当我运行生成的可执行文件时,出现以下错误:

dyld: Library not loaded: libtriangle.dylib
  Referenced from: /Users/zacharykraus/./main
  Reason: image not found
Trace/BPT trap: 5


当我运行otool -L main时,我得到

main:
    libtriangle.dylib (compatibility version 0.0.0, current version 0.0.0)
    /opt/local/lib/libgcc/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.20.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
    /opt/local/lib/libgcc/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)


如果我尝试将正确的路径导出到LD_LIBRARY_PATH或DYLD_LIBRARY_PATH。我犯了同样的错误。使可执行主程序运行的唯一方法是将主文件移至桌面。这将成功运行以产生:

the angles are 33.5496 61.5496 28
the sides are 2.2 3.5 1.86885


注意:我不认为三角形实际上存在,而是针对实际问题。
有人可以告诉我如何从不同于libtriangle.dylib所在的目录中运行该可执行文件吗?另外,为什么我的可执行文件仅在将可执行文件移到libtriangle.dylib所在的目录时才运行?

生成libtriangle.dylib的Fortran 90代码为:

!post all functions here
!double precision function area(side,angle)
!   double precision side(3),angle(3)
!end

double precision function sidelos(angle1,angle2,side2)
    double precision angle1, angle2, side2
    !law of sines to calculate the missing side
    sidelos=side2*sin(angle1*3.141593d0/180d0)/sin(angle2*3.141593d0/180d0)
end

double precision function anglelos(side1, side2, angle2)
    double precision side1, side2, angle2
    !law of sines to calculate the missing angle
    anglelos=asin(side1*sin(angle2*3.141593d0/180d0)/side2)*180d0/3.141593d0
end

double precision function sideloc(side1, side2, angle3)
    double precision side1, side2, angle3
    !law of cosines to calculate side 3
    sideloc=sqrt(side1**2 + side2**2 - 2d0*side1*side2*cos(angle3*3.141593d0/180d0))
end

double precision function angleloc(side1, side2, side3)
    implicit none
    double precision side1, side2, side3
    !law of cosines to calculate angle3
    angleloc=acos((side1**2 + side2**2 - side3**2) / 2d0/side1/side2)*180d0/3.141593d0
end

!post all subroutines here
subroutine asa(angle1, side3, angle2, angle, side)
    double precision angle(3), side(3), sidelos
    double precision angle1, side1, angle2
    integer i
    !f2py intent(out) angle
    !f2py intent(out) side
    angle(1) = angle1
    angle(2) = angle2
    side(3) = side3
    !calculate the third angle
    angle(3)=180-angle(1)-angle(2)
    do i=1,2
    !calculate the missing sides using law of sines
        side(i)=sidelos(angle(i),angle(3),side(3))
    end do
end

subroutine sas(side1, angle3, side2, angle, side)
    double precision angle(3), side(3), sideloc, anglelos
    double precision side1, angle3, side2
    integer i
    !f2py intent(out) angle
    !f2py intent(out) side
    side(1) = side1
    side(2) = side2
    angle(3) = angle3
    !calculate the missing side with law of cosines
    side(3)=sideloc(side(1),side(2),angle(3))
    do i=1,2
        !calculate the missing angles with the law of sines
        angle(i)=anglelos(side(i), side(3), angle(3))
    end do
end

subroutine sss(side1, side2, side3, angle, side)
    double precision angle(3), side(3), angleloc, anglelos
    double precision side1, side2, side3
    integer i
    !f2py intent(out) angle
    !f2py intent(out) side
    side(1) = side1
    side(2) = side2
    side(3) = side3
    !calculate the missing angle with law of cosines
    angle(3)=angleloc(side(1),side(2),side(3))
    do i=1,2
        !calculate the missing angles with the law of sines
        angle(i)=anglelos(side(i), side(3), angle(3))
    end do
end

subroutine aas(angle1, angle2, side1, angle, side)
    double precision angle(3), side(3), sidelos
    double precision angle1, angle2, side1
    integer i
    !f2py intent(out) angle
    !f2py intent(out) side
    angle(1) = angle1
    angle(2) = angle2
    side(1) = side1
    !calculate the third angle
    angle(3)=180-angle(1)-angle(2)
    do i=2,3
        !calculate the missing sides using law of sines
        side(i)=sidelos(angle(i),angle(1),side(1))
    end do
end


链接到动态库的C ++代码是:

extern "C" void sas_(double*, double*, double*, double*, double*);
#include <iostream>
using namespace std;
int main()
{
  double side1 = 2.2, side2= 3.5, angle3 = 28;
  double angle[3], side[3];
  sas_(&side1, &angle3, &side2, angle, side);
  cout << "the angles are ";
  for (double value : angle)
    cout << value <<" ";
  cout << endl;

  cout<<"the sides are ";
  for (double value : side)
    cout << value << " ";
  cout << endl;
  return 0;
}

最佳答案

答案与动态库在Mac OS X中的工作方式有关。 os x中的动态库始终将路径存储在库中。编译动态库时,默认路径是库的名称。在编译时链接动态库时,库中的路径将存储在可执行文件中。因此,当您尝试运行main时,可执行文件在当前目录中寻找libtriangle.dylib。这就是为什么如果将libtriangle.dylib复制到当前目录,则程序可以正确运行的原因。

要解决此问题,请添加-install_name和编译的绝对路径。比重新编译链接到libtriangle.dylib的c ++文件。重新编译后,重新运行otool -L main给出:

main:
/Users/zacharykraus/Desktop/libtriangle.dylib (compatibility version 0.0.0, current version 0.0.0)
/opt/local/lib/libgcc/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.20.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
/opt/local/lib/libgcc/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)


现在,可执行文件可以正常运行,而不必将动态库复制到当前路径。

关于c++ - Mac动态库疯狂(可能仅Fortran),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27162276/

10-10 21:00