Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28381 Discussions

Cannot resolve external symbol in C++ file in Fortran project

Gordon_B_
Beginner
610 Views

I am attempting to link to a c++ subroutine package from a Fortran project but continue to get

error LNK2019: unresolved external symbol _mcea referenced in function _DOWUNRUN

my C++package looks like

extern "C" //prevent function name from being mangled
#include "rayopt.h"
double seed,oldrand[55];
int jrand;

extern "C" __declspec(dllexport)

//********************************************************************************************
    void mcea(double seed, int no_solutions, double prob_crossover, double prob_mutation, double distribution_index_crossover,
        double distribution_index_mutation, int no_objectives, int no_constraints, int no_variables, double upp_bound[],
        double low_bound[], int type_variable[], double f77_parent_population[], double f77_parent_objective[],
        double f77_parent_constraint[], int parent_type[], double f77_child_population[], double f77_child_objective[],
        double f77_child_constraint[], int child_type[], int ii)
    {

etc

and my fortran call looks like

    Subroutine DoWunRun
    Use, intrinsic :: ISO_C_Binding
    Use Traj2dF_M
    include "Traj2df.fi"
    common/RWO/ig,Kruns
    integer i,j,k,ig,Kruns,Mode
!
      INTERFACE
      Subroutine mcea(Seed,NumSol,ProbX,ProbM,DIX,DIM,
     *  NumObjs,NumConstr,NumVars,ovMaxLim,ovMinLim,type_variable,
     *  parent_population,parent_objective,parent_constraint,
     *  parent_type,child_population,child_objective,child_constraint,
     *  child_type,Mode) BIND(C,NAME="mcea")
          Double Precision Seed
          Integer NumSol
          Double Precision ProbX,ProbM,DIX,DIM
          Integer NumObjs,NumConstr,NumVars
          Double Precision ovMaxLim(1),ovMinLim(*)
          Double Precision parent_population(*),parent_objective(*)
          Double Precision parent_constraint(*)
          Double Precision child_population(*),child_objective(*)
          Double Precision child_constraint(*)
          Integer parent_type(*),child_type(*),type_variable(*)
          Integer Mode
      END
      END INTERFACE  
!

     more code, then

        Mode=0
      call mcea(Seed,NumSol,ProbX,ProbM,DIX,DIM,
     *  NumObjs,NumConstr,NumVars,ovMaxLim,ovMinLim,type_variable,
     *  parent_population,parent_objective,parent_constraint,
     *  parent_type,child_population,child_objective,child_constraint,
     *  child_type,Mode)
!

etc

Whatever I try I still get the error.

Are there any Visual Studio settings I need to include?

Thanks in advance

 

 

0 Kudos
3 Replies
Lorri_M_Intel
Employee
610 Views

What version of Visual Fortran are you using?  And, I assume you're building a 32-bit application?

               --Lorri

 

0 Kudos
Steve_Lionel
Honored Contributor III
610 Views

You don't say how the C++ library is specified in by the linker in the Fortran project. I see a dllexport in the C++ code, so are you building a DLL? If you made the C++ project a dependent of the Fortran project, expecting the library to be pulled in automatically, that doesn't work with C++ DLL projects due to a change Microsoft made some VS versions ago. In that case you will have to name the .lib explicitly in the Linker "Additional Dependencies" property or add the .lib to your Fortran project as if it were a source file. Do make sure that the runtime library types of the two projects match.

0 Kudos
JVanB
Valued Contributor II
610 Views

I think Steve's suggestion will get you past the linking stage, but the C++ side is declaring all scalars to be passed by value while the Fortran interface is passing everything by reference. You need to fix this on the Fortran side by adding the declarations

        Value Seed,NumSol,ProbX,ProbM,DIX,DIM
        Value NumObjs,NumConstr,NumVars,Mode

At the end of your declarations in the interface body for subroutine mcea. Also your interface body should contain IMPLICIT NONE because it can't inherit implicit typing from its host, not even through an IMPORT statement. Not to mention that it is my preference that the Fortran dummy argument names should match the names given on the C++ side, not only for clarity (the C++ documentation could then be read as the Fortran documentation) but when the Fortran compiler spits out an error about an actual argument to mcea you can compare more easily the C++ documentation and your Fortran subroutine call.

0 Kudos
Reply