Click here to Skip to main content
15,890,185 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I've tried to build a project inside VS2019 IDE, where I call from a routine C++ a routine Intel Fortran passing some structures and inside the routine Intel Fortran I call a routine C++, but I've some problems in linking because the link does not recognize the routine called by C++ module. Previously I've been able to call the routine Fortran from the routine C++ and passing some structs without any error.
In particular I've got the following error:
Severity Code Description Project File Line Suppression State
Error error LNK2019: unresolved external symbol _Gprintf referenced in function _ADD1 Source1.obj

Thanks awfully in advance for your support.

What I have tried:

C++ code:
#include <iostream>

extern "C" {
    typedef struct
    {
        short int   nstream;
        short int   nunit;
        short int   ncomp;
    }  GENERALtype;
    typedef struct
    {
        float tau;
    } PItype;
}
extern "C" {
    __declspec(dllexport) void ADD1(GENERALtype* general, PItype* pi);
}

extern "C" {
    void Gprintf(short int msgcod, char *text) {
        printf("%d - %s\n", msgcod, text);
    }
}

int main()
{
    GENERALtype GENERAL;
    PItype PI;
    PI.tau = 2;
    ADD1(&GENERAL,&PI);
    
    std::cout << GENERAL.nstream;
    std::cout << GENERAL.nunit;
    std::cout << GENERAL.ncomp;
    std::cout << PI.tau;
}

Fortran Module containing the data exchanged with C++ by Fortran routine called by C++ (ADD1)
module extdata
    use, intrinsic :: iso_c_binding
    implicit none
    TYPE, BIND(C) :: GENERALtype
         INTEGER(C_SHORT) :: nstream, nunit, ncomp
    END TYPE GENERALtype
    TYPE, BIND(C) :: PItype
         REAL(C_FLOAT) :: tau
    END TYPE PItype
end module extdata

Fortran Module containg the routine ADD1 and the interface of C++ routine called by ADD1:
module FortranSub
          use, intrinsic :: iso_c_binding,only : C_SHORT, C_CHAR, 
     *    C_NULL_CHAR
          implicit none
          interface
          subroutine Gprintf(codemsg, string) 
     *     bind(C, name ='Gprintf')
           use, intrinsic :: iso_c_binding,only : C_SHORT, C_CHAR
              implicit none
              integer(C_SHORT), intent(in) :: codemsg
              character(KIND=C_CHAR), intent(in) :: string(*)
           end subroutine Gprintf
          end interface 
      contains    
          subroutine ADD1(GENERAL,PI) bind(C,name="ADD1")
          !DEC$ ATTRIBUTES DLLEXPORT :: ADD1
          use, intrinsic :: iso_c_binding
          use extdata
          TYPE (GENERALtype) GENERAL
          TYPE (PItype) PI
*          
          GENERAL%nstream=5
          GENERAL%nunit=1
          GENERAL%ncomp=3          
          PI%tau = 3.14159*PI%tau
          call Gprintf(69,C_CHAR_"Passaggio Stringa"//C_NULL_CHAR)
          return
          end subroutine
      end module FortranSub    
Posted
Updated 18-Nov-21 22:35pm
Comments
Richard MacCutchan 19-Nov-21 4:34am    
The link error is telling you that it is trying to bind to the name _Gprintf. In your C++ code you are trying to export ADD1, instead of importing it. And you have not exported Gprintf.

1 solution

See Creating and Using a Dynamic Link Library (C+) | Microsoft Docs[^] for the correct way to build a DLL.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900