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

Calling foreign Fortran compiled DLL possible?

h-faber
Beginner
668 Views

Hi,

is it possible to call a DLL which has been compiled (with dll_export instructions) with another Fortran compiler, e.g. Lahey? And furthermore, does it also work, if this external DLL calls another different compiled DLL? Maybe this is hard to understand, I better show:

A(Intel compiled program with dllimport::B) --calls--> B(Lahey compiled DLL) --calls--> C(Lahey compiled DLL)

Or do I need the sources from B and C, re-write them (change dll_import to dllimport etc.) and compile them under Intel?

At the moment I get error message about unresolved external symbol for the try to call a B-subroutine outgoing from A.

Hint: I still use IVF 8.1 in VS 2003.

Thanks in advance.

0 Kudos
7 Replies
anthonyrichards
New Contributor III
668 Views
If all the DLL's are compiled and linked to run as windows 32-bit libraries, then they should be compatible with each other. After all, all our Fortran-compiled libraries and executables are linked to Windows DLLs written in various languages and variously compiled and they still work!

However, what I think you may find is that the symbols you expect for a given DLL are not the same as the symbols actuallyexported with the DLL. You need to examine the DLL using DUMPBIN to see what symbols are actually exported and then match your Fortran DLLIMPORT's to them. Apparently, you must also get the calling conventions to match or you will likely get stack corruption problems. Beware!
0 Kudos
h-faber
Beginner
668 Views

Hi,

thanks for the quick and competent reply. I will try this out.

Now I fall into an ugly trap. I have something like

[fortran]cDEC$ ATTRIBUTES DLLIMPORT::AFunction

...

CHARACTER*18 AFunction

CHARACTER*18 AVariable

CHARACTER*16 BVariable

...

AVariable = AFunction(BVariable)

[/fortran]

But when I compile the project, I get this error message:

Error: This name has not been declared as an array or a function. [AFunction]

I have to admit that I have no idea about the AFunction-signature. I guess it returns a CHARACTER*18. If I remove the AFunction declaration CHARACTER*18 AFunction, I get another error message:

Error: A CHARACTER data type is required in this context. [AFunction]

What can I do now?

0 Kudos
Steven_L_Intel1
Employee
668 Views
There's more here than you have mentioned so far. For example, you seem to be compiling with the /names:asis option, which I strongly recommend against using. It wreaks havoc with normal Fortran rules. If you want to call an external procedure with mixed case names, declare the routine with the BIND(C,NAME="MixedCaseName") attribute or use !DEC$ ATTRIBUTES ALIAS to rename it.

I suspect that the error message you show is not coming from the code you showed. Can you show us a small but complete example and the actual and complete error messages?
0 Kudos
anthonyrichards
New Contributor III
668 Views
All the functions that you wish to use in a DLL must first be described to the compiler. This requires providing an INTERFACE block for each of the functions that you want to call from your DLL. The INTERFACE block will define the subroutine or function, define its arguments and define the calling convention to be used.

For example, the module USER32 compiled from file USER32.F90 contains interface blocks for all of the Windows API functions and subroutines in the Windows library USER32.LIB (or.DLL) that a 32-bit windows program may need to use.

So if, in your Fortran program, you want to use a Windows API function such as PostQuitMessage or CallWindowProc, you have to include the statement USE USER32 in order to make all the interface information for the functions available to the compiler so that it knows that when you code

MyProc=CallWindowProc(hPevProc, hWnd, Msg, wParam, lParam)

it 'knows' that you are referring toan Integer function CallWindowProc having four arguments, with the interface block from the USER32 module also describing the calling convention to be used (beware - the default calling convention used by your Fortran compiler may not match that used by the compiler that created the DLL or LIB) and any alias symbol that the default FORTRAN upper case name needs to be identified by in the DLL in which the code resides.

Clearly, it would save you much time, if you have access to the source code, to recompile the 'foreign' source using IVF so that the calling convention matches everywhere. I beleive that you can at the same time get the compiler to generate interface blocks for you.
0 Kudos
h-faber
Beginner
668 Views

Hi Steve,

the compiler goes with

/nologo /Zi /Od /module:"$(INTDIR)/" /object:"$(INTDIR)/" /traceback /check:bounds /libs:dll /threads /dbglibs /c/dll

and the Linker with

/OUT:"$(OUTDIR)/T2D211Intel.dll" /INCREMENTAL:NO /NOLOGO /LIBPATH:"D:\T211FF1" /DEBUG /PDB:"$(OUTDIR)/T2D211Intel.pdb" /SUBSYSTEM:WINDOWS /IMPLIB:"$(OUTDIR)/T2D211Intel.lib" /DLL

I do not have the foreign DLL as source, so you suggest to use the ATTRIBUTES ALIAS in my code, right? OK, will go for it.

Concerning error messages, well, somehow you are right. :-) In the first case I get *both* error message, in the second case only the "character data type required" one. That is it indeed. And it must come from the code I have shown because the variable AFunction appears nowhere else.

Is there a typical mistake known for this error message with this kind of programming, dll using?

0 Kudos
Steven_L_Intel1
Employee
668 Views
Did you retype the error message or did you cut and paste it? Please always cut and paste error messages - errors can be introduced through transcription.

Please attach the actual and complete source you are compiling.
0 Kudos
h-faber
Beginner
668 Views

Hi Steve,

the sourcecode has some thousand lines, that would not be helpful to paste. ;-)

In the meantime I solved the problem with anthonyrichards idea by using INTERFACE. Thanks a bunch to both of you.

Now I will soon be able to investigate whether the foreign dlls work. Will let you know when they don't. ;-)

0 Kudos
Reply