0

My objectif is to rename a fortran subroutine inside a module to be easily callable by C code (i.e. without the __<modulename>_MOD_ prefix), and using GCC-6.3.0. I cannot use bind(c,name='') even if it works great. I have read that I should use interface, but without any success. Here is the MWE:

module testmodule
    interface
       subroutine func02
       !GCC$ ATTRIBUTES CDECL :: func01
       end subroutine
    end interface

    contains

    subroutine func01
      print*,"func01"
    end subroutine
end module 

I compile using command gfortran -c test.f90 and then I check if the subroutine is correctly renamed using nm test.o, but there is no sign of func02. Any help appreciated.

ThomasGuenet
  • 183
  • 1
  • 7
  • 17
  • Have you tried with the DLLEXPORT attribute? – Rodrigo Rodrigues Jun 22 '18 at 14:15
  • 1
    Why can't you use `bind(c)`? Whatever stops you using that may also stop you using any other suggestion, so it would be useful for you to clarify. – francescalus Jun 22 '18 at 14:20
  • 1
    @RodrigoRodrigues DLLEXPORT did not work either. Also I am working on Linux. @francescalus It is more than 10000 lines of code with high complexity, using `bind(c)` changes many thing starting with c-structure that are transmitted from C to Fortran very differently (with a `void *`). I need this specific MWE to work. Thanks both for your interest in the question. – ThomasGuenet Jun 22 '18 at 14:30
  • If there is some important change that BIND(C) makes to the nature of your procedure, then your example needs to include that so that we can advise you appropriately. If you have existing C code calling an existing Fortran procedure, but with a long funny _MOD_ name, then it should be reasonably straight forward to construct a BIND(C) wrapper (you don't have to change the original Fortran - you can add another procedure as an intermediate) for that existing procedure that maintains binary compatibility, bar the name. – IanH Jun 23 '18 at 07:33

1 Answers1

1

You can use BIND(C) to rename the subroutine. Whatever you read about INTERFACE seems to be a red herring.

module testmodule
   contains
      subroutine func01() bind(c, name='func2')
         print*,"func01"
      end subroutine
end module

With the simple command 'gfortran -c a.f90', I see the following results

nm a.o
     U _gfortran_st_write
     U _gfortran_st_write_done
     U _gfortran_transfer_character_write
00000000 T func2
evets
  • 996
  • 1
  • 5
  • 6
  • sorry but bind(c) is forbidden for me like I explained. I agree you code works, but it will not for me. – ThomasGuenet Jun 22 '18 at 14:42
  • @ThomasGuenet, What to you mean forbidden? – evets Jun 22 '18 at 15:00
  • I cannot use it because of complexe fortran code structure implying changing too many code. Hence `bind(c)` is a solution for anyone starting a new project, but I asked for another solution : it is the purpose of this question. – ThomasGuenet Jun 22 '18 at 15:18
  • @ThomasGuenet, there is no other solution. gfortran purposefully name mangles module subprograms to try to isolates the namespace of both gfortran and the module from clashes with anything in the user namespace. `BIND(C)` is the only way to override the name mangling within the Fortran code. – evets Jun 22 '18 at 15:27
  • 2
    You can use `bind(c)` in a single place to generate a correct binding name and not use it anywhere else. I don't understand how `bind(c)` would cause any issue to the rest of your code base. – Pierre de Buyl Jun 22 '18 at 15:30
  • 1
    @evets, It's not impossible. ThomasGuenet, you can use gfortran to generate an assembly file. Feed that file through sed to strip out the prefix. Then use gfortran to compile the sed-edited assembly. Good luck, or use BIND(C). – Steve Jun 22 '18 at 17:53