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

sharing global data to DLL

krishnabc
Beginner
1,262 Views
I would like to share some data to a DLL and greatly appreciate your suggestions. Here are the steps that I have followed, but was unsuccessful.
1. I created a very simple DLL with a globaldata.
2. I used this DLL in a main program successfully following the DLL_Shared_Data sample example.
3. However, I was unsuccessful to use the globaldata DLL in another DLL. It is giving 'unresolved external symbol error LNK2019 for the globaldata variable'. Here, copying only the globaldata DLL to the project file was also not enough. I had to copy the .mod file of globaldata as well, but the error still persists. Do I need to make any changes in the project/linker settings?
Below are the sample codes:
Code for globaldata DLL
[fortran]Module globaldata
implicit none
integer :: ivar = 6
!DEC$ ATTRIBUTES DLLEXPORT :: ivar

end module globaldata[/fortran]
Code for main program (working fine)
[fortran]    program Main_Program_Global_Data_DLL
    use globaldata
    implicit none
    
    ! Variables

    ! Body of Main_Program_Global_Data_DLL
    print *, 'Hello World'
    write (*,*) 'In main program IVAR from DLL =', ivar
    ivar = 10
    write (*,*) 'in main program, modified IVAR =', ivar

    end program Main_Program_Global_Data_DLL[/fortran]
Code for another DLL using globaldata DLL (giving LINKing errors during compilation)
[fortran]subroutine DLL_with_Global_Data
  !DEC$ ATTRIBUTES DLLEXPORT::DLL_with_Global_Data

  USE globaldata
  IMPLICIT NONE
  ! Variables
  INTEGER :: i
 ! Body of DLL_with_Global_Data
i = 5 WRITE (*,*) 'In DLL call, IVAR from DLL =', ivar ivar = ivar + i WRITE (*,*) 'In DLL call, modified IVAR in DLL_Global_Data_Main =', ivar end subroutine DLL_with_Global_Data [/fortran]
Thank you for your help.
Krishna
0 Kudos
1 Solution
IanH
Honored Contributor III
1,262 Views
The solution was given in post #1 - you need to include the globaldata.lib file in the link step of projects that want to use the DLL. Neither the Main_Program_Global_Data_DLL or DLL_with_Global_Data projects that you attached do that.

You can either add the relevant lib file directly to the project as if it was a source file - right click on the project name, select Add > Existing item, then navigate to the relevant lib file; or include the directory that contains the lib file in the project properties under Linker General > Additional Library Directories and then put the name of the lib file under Linker > Input > Additional Dependencies (and repeat for each configuration).

Depending on your VS version, dependent lib files may be linked in automatically if the projects are in the same solution and the necessary dependencies are set.

View solution in original post

0 Kudos
8 Replies
onkelhotte
New Contributor II
1,262 Views
I think you have to link the globaldata.lib in your DLL_with_Global_Dataproject.

Then the compiler knows, that there are certain functions / subroutines / modules, but what exactlyto do is known at run-time.

Markus
0 Kudos
krishnabc
Beginner
1,262 Views
I tried including all three files with .dll, .lib, and .mod extensions. However, it is still giving the LINKer error.

Thanks.
Krishna
0 Kudos
onkelhotte
New Contributor II
1,262 Views
Can you attach your sample project(s)?
0 Kudos
krishnabc
Beginner
1,262 Views
Hi,
I have attached the sample project files. If I create the 'main program' project and 'globaldata' dll project in the same solution, as in DLL_Shared_Data sample example, it is working fine. However, if I create all the projects separately, and copy the globaldata.dll and globaldata.lib files manually to the main project or other DLL project, I am getting the 'external symbol linking' error. I do not know what I am missing to link.
Thanks for your help.
Krishna
0 Kudos
krishnabc
Beginner
1,262 Views
Appreciate if someone can help resolve this linking issue or suggest a way to pass the global data to end user without exposing them the source code.
Thank you very much.
0 Kudos
IanH
Honored Contributor III
1,263 Views
The solution was given in post #1 - you need to include the globaldata.lib file in the link step of projects that want to use the DLL. Neither the Main_Program_Global_Data_DLL or DLL_with_Global_Data projects that you attached do that.

You can either add the relevant lib file directly to the project as if it was a source file - right click on the project name, select Add > Existing item, then navigate to the relevant lib file; or include the directory that contains the lib file in the project properties under Linker General > Additional Library Directories and then put the name of the lib file under Linker > Input > Additional Dependencies (and repeat for each configuration).

Depending on your VS version, dependent lib files may be linked in automatically if the projects are in the same solution and the necessary dependencies are set.
0 Kudos
krishnabc
Beginner
1,262 Views
Dear IanH,
Thank you very much. The linking error is resolved after adding the .lib file directly to the project as if it was a source file.
I have another issue for using the DLL file now. The GetProcAddress returns NULL. The coding seems fine to me, but still can't move ahead. Hope you or someone can shed some light on this.
[fortran]    program Main_Program_Global_Data_DLL
    !use ifwin
    use kernel32
    use globaldata
    implicit none
    integer :: i
    
    interface
      subroutine DLL_with_Global_Data()
      !DEC$ ATTRIBUTES DLLIMPORT :: DLL_with_Global_Data
      end subroutine DLL_with_Global_Data
    end interface
       
    integer(handle) :: dll_handle
    !INTEGER(LPVOID) :: p_USERDLL
    pointer (p_USERDLL,DLL_with_Global_Data)
    
    ! Variables

    ! Body of Main_Program_Global_Data_DLL
    print *, 'Hello World'
    write (*,*) 'In main program IVAR from DLL =', ivar
    ivar = 10
    write (*,*) 'in main program, modified IVAR =', ivar
 
    ! Calling data from DLL or subroutine

      write (*,'(A)') "Loading library..."
      dll_handle = LoadLibrary ("./DLL_with_Global_Data.dll"C)
      ! Check for errors
      if (dll_handle == NULL) then
        ! Failure
        write(*,*) ' --- loading DLL'
        stop
      end if


      !Look up the routine address.  

      write (*,'(A)') "Getting routine address..."
      p_USERDLL = GetProcAddress(dll_handle, "DLL_with_Global_Data"C)

      if (p_USERDLL == NULL) then
        ! Failure
        write(*,*) ' --- looking up routine'
        stop
      end if

      CALL DLL_with_Global_Data()
    
    end program Main_Program_Global_Data_DLL[/fortran]
Thank you.
0 Kudos
krishnabc
Beginner
1,262 Views
Sorry for the trouble.
Now everything is working fine.
Has to add ALIAS attibute together with DLLEXPORT for a globalname of the function/subroutine in DLL.
Many thanks for your help.
0 Kudos
Reply