0

I have a C function that uses structures. I developed a Fortran Wrapper which calls the C function. Both libraries are built successfully. I have passed the variables form the PSCAD model and run the case. The PSCAD model is throwing the error.

Error Message:

Type    Id  Component   Namespace   Description
            dll_df  FORTRA~1.LIB(dlltestx.obj) : error LNK2019: unresolved external symbol _test_cfun referenced in function _AUX_CFUN

C-Code:

// This is an example of an exported variable
    typedef struct _goose_c
    {
       int in1;      
       float in2;
    }goose_c;


    __declspec(dllexport) void test_cfunc(goose_c *V, double *out1)
    {
       //*out1 = (*V).in1 + (*V).in2;
       *out1 = V->in1 + V->in2;
    }

Fortran Wrapper Code:

  SUBROUTINE AUX_CFUN(ip1, ip2, out1)
        
       use, intrinsic :: iso_c_binding
       
       implicit none           
       integer, intent(in)  ::  ip1
       real,    intent(in)  ::  ip2
       real,    intent(out) ::  out1 
   
       type, bind(C)   :: goose_t
       integer(c_int)  :: in1
       real(c_double)  :: in2
       end type goose_t                     
          
       type(goose_t) :: goose_f             
          
       ! Fortran 90 interface to a C procedure
       INTERFACE
           SUBROUTINE TEST_CFUN (goose_f,out1) bind (C)
               use iso_c_binding                   
               import :: goose_t
               type(goose_t), intent (in)   :: goose_f
               real(c_double), intent (out) :: out1
           END SUBROUTINE TEST_CFUN
       END INTERFACE 
       
       goose_f%in1 = ip1
       goose_f%in2 = ip2
       
       ! call of the C procedure
       CALL TEST_CFUN(goose_f,out1)           
       RETURN
   END SUBROUTINE AUX_CFUN
Ian Bush
  • 6,996
  • 1
  • 21
  • 27
  • 4
    You define `test_cfunc` in the C, but call it `test_cfun` in the Fortran? – francescalus Jul 06 '21 at 18:31
  • Does this answer your question? [What is an undefined reference/unresolved external symbol error and how do I fix it in Fortran?](https://stackoverflow.com/questions/66855252/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – veryreverie Jul 19 '21 at 12:25

1 Answers1

0

The bind (C) clause in the interface should be completed with the exact (including the correct case) C name of the function you want to interface; so in your example it should read bind (C, name='test_cfunc'). The Fortran name associated to the C function (TEST_CFUN in your example) can be in principle different, it's up to you to decide whether this is a good idea or not, and it is used in your fortran program with the usual fortran rules, so it is case-insensitive.

Davide
  • 196
  • 1
  • 4
  • It could be better to answer the [canonical question](https://stackoverflow.com/q/66855252/3157076) instead of this one (which is most likely simply a typo rather than a conscious effort to use different names). – francescalus Jul 08 '21 at 10:59
  • Yes you are right, I forgot that not indicating a `name` option in the `bind(C)` clause is not an error and it is equivalent to specifying that the C name is equal to the lowercased Fortran name; however I think it's a good practice to explicitly indicate the C name, to avoid ambiguity. – Davide Jul 15 '21 at 11:42