- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I need to call a 3rd party DLL from within the Fortran application. Can someone tell me or point me to some documentation (preferably step-by-step) that explains how to do this? I need help with pretty much all the steps. How do I tell Fortran about the ".lib" file? How do I get the ".lib" file to link in? Do I need to create some kind of interface in order to use the dll? Is there any chance of getting intellisense to work with it? How do I tell the IDE to include a folder in the search path at run/debug time?
Any/all help would be appreciated!
Thanks!
Brad.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You won't be able to get Intellisense to work for it. As for the search path, you will need to add the path to the DLL to the PATH environment variable before you start the IDE.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So I tried that: I added the ".lib" file as a source file to the project.If I then add a "use" statement to my source, I get"Error 1 error #7002: Error in opening the compiled module file. Check INCLUDE paths." Alternatively, if I try simply calling the routines (as you suggest) without a "use" statement, I get "Error 1 error LNK2019: unresolved external symbol _ROUTINENAME referenced in function _MAIN__".
What am I doing wrong? Where do I go from here?
Thanks again,
Brad.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you have a third party library in DLL form, you also need, in addition, i) the corresponding import library file (*.lib) or a module definition file (*.def) which can be used to build the import library file, and ii) the module file (*.mod) that contains the definitions of and interfaces to module entities.
Please note that "module" is used in two rather independent senses here. The linker has one concept of the word, going back to IBM mainframes of the 1960s, and the Fortran compiler has another concept of module, which was introduced with Fortran 90.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!
Brad.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, only the Fortran compiler can produce .mod files and it does so if the source code for the module is available.
Without a .mod file, it is impossible to compile any source that has a USE statement for that module. You may try to obtain the .mod file from the author of the DLL, or fall back to calling the DLL routines with explicit or implicit interfaces that you provide in your source code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks!
Brad.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In that case, you are in good shape.
There are several include files in the MKL include directory upon which you may model your interface code. The Intel Fortran Reference contains a section called Procedure Interfaces.
You may put the interface body inside the routine that calls the corresponding DLL routine(s).
If you want to avoid having to multiple copies of interfaces, you can create a module that contains nothing but just the interface declarations, and USE that module wherever needed. Once you compile the module source, you will have the hitherto missing .mod file that the author/vendor of the DLL should have provided.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1) write your own third-party DLL program by Creating a DLL project containing a single subroutine that takes three real arguments. The first two reals should be the numbers to be added, the routine should add them and return the result in the third variable. This is straightforward Fortran programming.
Write the code for this but remember to include a DLLEXPORT compiler directive to 'export' the name of the subroutine. This means that the non-executable .LIB file that is generated at the same time as the .DLL executable code will then contain a list of all names of all the members members included in the DLL that you have decided to make visible to the outside world. In this case it will a list of one name, that of the routine you hacve written. If you omit the 'DLLEXPORT' of the name, the subroutine will be invisible to the outside world and the linker will not be able to find it in the DLL.
2)Creat a simple 'Hello world' console program to test the DLL. Add code to the default 'Hello World' generated code to define three real variables and assign values to two of them.
Add a compiler directive to IMPORT the name of the subroutine that you want to use from the DLL (there is only one at this stage). Then add a call to the DLL subroutine using the three variables as arguments and get the subroutine to return the sum in the third variable.
The compiler will use the contents of the DLL's .LIB file to get all the information it needs about the DLL and in teh list of symbols it finds it will look for a symbol having the name that you use for the subroutine you want to call. Hopefully, if you have not spelled it wrong, the compiler will find it and the linker will do all the necessary linking to load the DLL and call the subroutine.
P.S. The Fortran compiler comes with a utility called DUMPBIN which, used with a DLL or a DLL's .LIB file as an argument and the appropriate switch will list the names of all the exported symbols present in the DLL. Be warned, that depending on the calling convention specified for use in your interface blocks, the compiler may add a leading underscore to the straight symbol name and may even add a trailing @12 to the name (specifying that the routine expects an argument list of 3 variables supplied by reference, each address reference requiring 4 bytes, making 12 bytes in total.
ALso note that Case is SiGniFicanT in symbol names and that FORTRAN normally forces all routine names referenced in its code to be UPPERCASE unless sternly told not to do so (using the appropriate compiler directive), so if mixed case names occur in your third-party DLL, you need to establish exactly what they are and use the 'ALIAS' directive to tell the Fortran compiler to use that rather than the Upper case name.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How do I get the information in the *.lib file to link into the executable properly? I've included the *.lib file as a "Source File", but that appears to be insufficient.
Thanks again!
Brad.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also, the routines definitely used mixed case. Can you provide more details about the "ALIAS" directive?
Thanks!
Brad.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It may be worthwhile at this point for you to work with a small example, get the problems taken care of using it (posting here as needed), and then apply the same techniques to your real code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
MYDLL.F90 contains code to create a DLL called MYDLL.DLL.
The DLL contains two subroutines, both of which take 3 real arguments, adding the first two numbers and equating the total to the third. The wrinkle I have added is to give one of the subroutines an alias which exports a mixed case name for it to the symbol table that is created in the MYDLL.LIB file that is created alongside the MYDLL.DLL.
To show what turns up in the MYDLL.DLL, I attach the output file MYDLL_DUMPBIN_OUTPUT.TXT obtained by running the utility DUMPBIN on MYDLL.DLL using the command (from within the MYDLL.DLL /debug/ or /release/ folder)
>dumpbin /exports /OUT:MYDLL_DUMPBIN_OUTPUT.TXT mydll.dll
As you can see, the linker exports the correct mixed-case name as required and also exports two versions of the default upper-case name for the second routine. The one ending '@12' is referred to as 'decorated'.
To test the DLL, I attach the files TESTMYDLL.F90 and a module file MYINTERFACES.F90. The latter contains interface blocks that tell the compiler what symbols to look for in the external source (in this case MYDLL.DLL), with the 'ALIAS' part of the directive giving the case-preserving symbol name when required. When creating the project, these two files need to be supplemented by the MYDLL.LIB file that you will find in the /MYDLL/debug/ folder (or /release folder if release version being tested) along with MYDLL.DLL once you have built the MYDLL.DLL library. Just use 'Add item' or 'Add to Project' to add the .LIB file to the TESTMYDLL project.
In order to test the DLL, you will need to copy MYDLL.DLL from the folder it was created in to the /debug/ or /release/ folder of the TESTMYDLL project.
Here is what to expect when you run the TESTMYDLL test program:
Hello World, Here is a test of MYDLL that tries to use a mixed-case subroutinename
from Mixed Case Subroutine: X = 2.00000000000000 , Y =3.00000000000000 , SUM = 5.00000000000000
from UPPER CASE Subroutine: X = 5.00000000000000 , Y =10.0000000000000 , SUM = 15.0000000000000
Fortran Pause - Enter command
I would recommend the following steps:
1) Creat an empty workspace
2) Create a new project, selecting Dynamic link library, with no files, and add it to the blank workspace
3) Add MYDLL.F90 to the DLL project.
4) compile and build the DLL
5) Create a new empty console project, add it to the same workspace
6) add TESTMYDLL.F90 and MYINTERFACES.F90 to the console project.
7) Add MYDLL.LIB to the console project, using ' Add Item' or ' Add file' and navigating to the /MYDLL/debug/ or /release/ folder where it will be created alongside the DLL.
8) compile and build the TESTMYDLL project
9) Execute the TESTMYDLL.EXE
All this is most easily done using the Visual Studio environment, but others more familiar with the command-line can advise you how to do what I propose from there.
Hope this helps!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My .lib was developed by another agency using the Intel compilers; using the Command Line to build it.
About all I presently offer up is 'moral support' but hopefully soon we will both work through this.....
I'm sure glad this Forum is here as I have no other support of use!!!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I realize that this error can mean almost anything, but has anyone got some suggestions of common problems with COM that produce this problem?
Thanks!
Brad.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Brad.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page