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

Dynamic DLL Loading

Ilie__Daniel
Beginner
635 Views

Hello!

I have a cosole program written in Fortran and I want to dynamically load a DLL, which can be written by a thrid party. The problem is that the DLL can be written in C++ or Fortran. The headers to the routines in the DLL are preset. What flags have to be specified in the DLL:

  1. on the DLLEXPORT line? (pressumably something like ATTRIBUTES DLLEXPORT, ALIAS:"USERFUNC" :: USERFUNC)
  2. on the argument declaration lines? (REFERENCE or VALUE)

so that the routines in the DLL can interface with the main Fortran program. What attributes should I include so that the correct routine names are exported to my Fortran application? I use the /iface:CVF for all my files.

On a side issue:

As I understand, variables in Fortran are passed by reference rather than by value. Correct me if I'm wrong! If you take the following pseudo-code:

program main

i=0

call sub(i)

print*,"i=",i

end program

sub(j)

j=j+1

print*,"j=",j

end sub

If variables are passed by reference then the output is: j=1, i=1.

If variables are passed by value, then the output is: j=1, i=0.

Am I getting this right?

Thanks and regards,

Daniel.

0 Kudos
5 Replies
Steven_L_Intel1
Employee
635 Views

If you are using /iface:cvf, then your C++ code will need to use __stdcall in the prototype for the Fortran routine. You may not need to add an ALIAS - how is the routine declared in C++?

Yes, pass by reference is the default. This can change if you use certain attributes such as C or STDCALL in directives. You can also specify VALUE on a !DEC$ ATTRIBUTES directive for the argument, or can use the Fortran 2003 VALUE attribute. The difference is that with !DEC$ ATTRIBUTES VALUE you cannot modify the argument inside the routine, whereas with the F2003 VALUE you can but are modifying a temporary copy that is discarded on exit.

0 Kudos
Ilie__Daniel
Beginner
635 Views
The routine is exported as __stdcall (void EXPORT __stdcall func1(double&arg) ).

0 Kudos
Steven_L_Intel1
Employee
635 Views

Ok. In that case the directive you'll want is this:

!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: func1

This will apply the correct name case (lowercase) and decoration and also specify pass-by-reference.

0 Kudos
Ilie__Daniel
Beginner
635 Views

Ok. In that case the directive you'll want is this:

!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE :: func1

This will apply the correct name case (lowercase) and decoration and also specify pass-by-reference.

One more thing, Steve: Is it mandatory to specify thedirective in uppercase?

0 Kudos
Les_Neilson
Valued Contributor II
635 Views
Quoting - Daniel I.

One more thing, Steve: Is it mandatory to specify thedirective in uppercase?

No. It's just a style thing - it stands out in the code better.

Les

0 Kudos
Reply