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

Write to files in a DLL

marcellocattaneo
Beginner
1,068 Views
I'm converting a library that is currently built as a static library to DLL, and I have a problem with writing
messages to a file that has been opened in the calling program.

A review of the Programmers Guide and of past forum posts seems to indicate that in order to share the file system between a Console application and a DLL one must link the Console application with the single-threaded DLL library (in DevStudio, project/settings/Fortran/libraries/use run-time library/debug single-threaded DLL ).

But when I add this setting to the Console application I get the following error message when linking:

LINK : error LNK2001: unresolved external symbol _mainCRTStartup
Debug/Main_Cons_OpenFile.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

When I eliminate the DLL library, the project links correctly, but then the procedures in the DLL do not see the files that where opened outside the DLL.

Below are two short source files that I'm using to research this problem. Main program is Cons_OpenFile, which is compiled as a Console application. The DLL is DLL_ReadFile

!***************************************************
program Cons_OpenFile

!DEC$ ATTRIBUTES DLLIMPORT :: MyProc

implicit none

interface
subroutine MyProc ( ff )
!DEC$ ATTRIBUTES DLLEXPORT :: MyProc
!DEC$ ATTRIBUTES ALIAS: 'MyProc' :: MyProc
use dfwin
integer:: ff
logical:: opn
end subroutine MyProc
end interface

integer:: ff, ios
logical:: opn

ff = 8

open( ff, FILE= 'TestLog.log', &
STATUS='UNKNOWN', IOSTAT=ios )

inquire(ff, OPENED= opn)

print * , 'Is it open in Main ?', opn

call MyProc (ff)

end program

!***************************************************
module dll_readfile

implicit none


contains

subroutine MyProc ( ff )

!DEC$ ATTRIBUTES DLLEXPORT :: MyProc
!DEC$ ATTRIBUTES ALIAS: 'MyProc' :: MyProc
use dfwin
integer:: ff, ret
logical:: opn

inquire(ff, OPENED= opn)

print * , 'Is it open in the DLL ?', opn

end subroutine MyProc

end module dll_readfile

!******************************************************



A second issue has to do wuth the types of projects that can be converted to DLL.

It is clear from the documentation that QuickWin projects cannot be converted to DLL's, which means one cannot use QW dialog boxes, message boxes etc. from within the DLL.

Can QW Projects call DLL's? and in this case, what are the run-time libraries to be used, both in the main (QW) project and in the DLL?

This part is not really clear in the Programmer's guide, which only indicates that you must 'make sure that libraries are compatible between DLL and executable'



Any help would be greatly appreciated.

Marcello Cattaneo
0 Kudos
5 Replies
marcellocattaneo
Beginner
1,068 Views
Further to the previous message.

The error messa ge I copied was the wrong one. What I'm actually getting is below:

msvcrtd.lib(MSVCRTD.dll) : error LNK2005: __imp___fpieee_flt already defined in dfordlld.lib(fix.obj)
Debug/ConsoleTest.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.


sorry ...

Marcello Cattaneo
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,068 Views
I'll reply only to this part:

It is clear from the documentation that QuickWin projects cannot be converted to DLL's, which means one cannot use QW dialog boxes, message boxes etc. from within the DLL.

Yes, but it's also unclear from documentation that DFLOGM is not part of QuickWin, i.e. that one doesn't need to link against QuickWin libraries when using DFLOGM, i.e. it is possible. The only thing to take care about is that you have to use DlgInitWithInstanceHandle (is it the right name?), since handle of Dll module is different than handle of calling exe. (You can get it if you write your own version of DllMain or by calling GetModuleHandle("Mydll.dll"C))

Can QW Projects call DLL's? and in this case, what are the run-time libraries to be used, both in the main (QW) project and in the DLL?

AFAIK only in case when modules share unit names or allocate/deallocate each other's memory, you must link with DLL version of RTL. In other cases, static version will suffice (although its code, of course, will be duplicated).

Jugoslav
0 Kudos
marcellocattaneo
Beginner
1,068 Views
thanks , Jugoslav.

I'm not at all familiar with windows programming, so I'm a little lost on the first part of you answer. In any case my most pressing need was to get some output to the user, and for that I can use a MessageBox call instead of MessageBoxQQ (there is a reply to another similar question from SL with this suggestion).

Unfortunately, as you say, using a static version of the RTL, the DLL module does not access units opened in the calling module, and therefore one should use the DLL RTL's if the DLL needs to write to files which were opened in the calling application.

And this is the problem of my first question: at this moment I'm not even able to link a Console module and a DLL module using the DLL RTL without getting a link error.

Any suggestions on how to do this?

Marcello


0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,068 Views
As for the first part of your question -- have you searched the Forum? See this thread.

Re the DFLOGM, you can use dialogs from your Dll (but not MessageBoxQQ, you're right), but you must use DlgInitWithResourceHandle routine for dialog loading (everything else is as usual). See docs on DlgInit.

Jugoslav
0 Kudos
marcellocattaneo
Beginner
1,068 Views
I finally figured it out: when linking a console project with the DLL library you must also go to Settings -> Link-> Customize and enable the Force file output option.

Now the modules link properly and the DLL can read/write files which have been opened in the main app.

The help for the FORCE option warns that you can get unexpected behavior, but I'm keeping my fingers crossed ...

Marcello
0 Kudos
Reply