0

I would like to call a .dll written in C into my Fortran code. I know that similar questions has been asked but the answers do not seem to work for me. I tried to read the file like follows:

 use, intrinsic :: ISO_C_Binding 

[...]

 ! ------------------------- including the controller-.dll -------------------------------
   interface 
        subroutine Controller ( data, status, infile, out, msg)  bind (C, NAME='Controller .dll') 
            use, intrinsic :: ISO_C_Binding
    
             real(C_FLOAT),          intent(inout) :: data(*)        
             integer(C_INT),         intent(inout) :: status 
             character(kind=C_CHAR), intent(in)    :: infile(*)      
             character(kind=C_CHAR), intent(in)    :: out(*)     
             character(kind=C_CHAR), intent(inout) :: msg(*)        
       end subroutine controller
    end interface 

The syntax seems to be right since I do not get any error messages. But when I try to call the subroutine:

call Controller(ctrl_data,ctrl_status,ctrl_infile,ctrl_out,ctrl_msg)

I get the error message "error LNK2019: Reference to unlisted external symbol "Controller" in function "MAIN_STRUCTURE". main_structure.obj"

Furthermore, I am not entirely sure where to put the Contoller.dll. To make sure it can be found it is in the same folder as the source code as well as in the working repository.

I am using the ifort compiler and Visual Studio 2019.

I look forward to all responses. Thank you in advance.

David

  • Are you sure the symbol you want from the DLL is called `Controller .dll` (particularly with that space - which your compiler seems to not like)? – francescalus Aug 25 '22 at 08:44
  • No, the space has crept in. I had tried to compile the code without it. – DavMaer Aug 25 '22 at 09:01

1 Answers1

0

I see three issues:

  • It looks unlikely that the C routine you're trying to call is named "Controller.dll". name in bind(C,name="...") should be the name of the function you're trying to call from the DLL, not the name of the DLL file.

  • If the library is to be statically linked to your program, you need an IMPORT library, not the .dll file. see How to generate an import library (LIB-file) from a DLL? on how you can export the definitions and build an import library file from a .DLL file

  • Finally, you need to ensure that the import library is properly set in your project, as LNK2019 error means the linker cannot find it. If all of the above items are OK, you need to ensure the path to the import library file is added to the project's dependencies (in Visual Studio: Properties->Linker->Input->Additional Dependencies)

Federico Perini
  • 1,414
  • 8
  • 13
  • I'm not sure what the linker does, but if you have conflicting names from different static libraries it will be a problem anyways: either the linker stops with an error, or you don't know what version of the function is being loaded into the executable. see https://stackoverflow.com/a/9183400/4702870 – Federico Perini Aug 25 '22 at 13:12
  • Unfortunately, I am new to those libraries. Why do you think that I need the LIB file instead of the DLL? – DavMaer Aug 25 '22 at 14:51
  • Actually the names of the DLL and the subroutine I would like to call have the same name. I deleted the suffix in controller.dll. but still get the same error message. – DavMaer Aug 25 '22 at 14:53
  • If I understood the difference correctly, I think the DLL is what I need. In the programm several iterations are performed. Not in everyone of them I want to use the Code. – DavMaer Aug 25 '22 at 15:01
  • The dynamic/static linking only affects if a subroutine is loaded or not into the executable, not if/how often it is called by the program. If you want to do dynamic linking, there's a very good answer at https://stackoverflow.com/questions/38710099/fortran-dynamic-libraries-load-at-runtime – Federico Perini Aug 25 '22 at 15:52
  • thank you for that hint. If I'm using the DLL, do I still have to add the path in the project dependencies (Properties->Linker->Input->Additional Dependencies), as it would be necessary if I had the LIB file? - I tried, but still stuck with the same error message. – DavMaer Aug 26 '22 at 09:44
  • If you are now doing dynamic linking, and have declared the function interface `abstract` as in the link, it should not be necessary to include it as an additional dependency – Federico Perini Aug 26 '22 at 10:02