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

Fortran derived type arguments in DLL subroutines

Jacob_Williams
New Contributor III
1,678 Views

I'm upgrading an application to allow for dynamically-loaded DLLs created by the user.  (I'm basing it on the DynamicLoad Intel example).  For my case, one of the arguments to the main subroutine that will be required in the DLL is a derived type.  A dumbed-down example is below:

type :: mytype
  integer :: i = 0
  character(len=:),allocatable :: name
  type(mytype),pointer :: next => null()
end type mytype

Note that it contains an allocatable character string, which is not interoperable with C, based on my understanding.  It also contains pointers that are used to construct a linked list.  The mytype dummy argument for the DLL routine is also a pointer.  My questions are:

1. Is it OK to have DLLs on Windows with derived types arguments that contain variables that aren't C-interoperable?

2. Should I include a SEQUENCE statement in this type?  It seems to work with or without it.

3. I presume the DLL can only be written in Fortran, unless I were to refactor the type to use interoperable character arrays and c_ptr's?  As it is now, would it work with any Fortran compiler, or would it have to be Intel?

4. Is it enough to publish the mytype declaration, and have the user declare it themselves within their DLL?  Is that a problem that the type is defined twice (once in my main program and once in their DLL)?  Does SEQUENCE make this OK?  Or, would BIND(C) make this OK?

Any help  would be appreciated!  Thanks in advance!

0 Kudos
11 Replies
Steven_L_Intel1
Employee
1,678 Views
  1. Yes. There's really no difference between a routine in a static library or link and one in a DLL, other than dependencies on other DLLs. If your DLL will be called from a Fortran main program, the main program and your DLL must be linked to the same DLL run-time libraries. C interoperability is just that, interoperability with C. DLLs are not important to that.
  2. You don't need SEQUENCE.
  3. Yes, with allocatable and pointer types, that requires a Fortran caller and you must use the same Fortran for all compiles. There is generally no interoperability across different Fortran compilers.
  4. Ideally you would define the type (and routine) in a module and make that accessible to the caller. If you make the caller redeclare it, that violates language rules (unless you use SEQUENCE), but will probably work. BIND(C) wouldn't have an effect on this, unless of course the caller was C in which case the C code would have to have its own declaration.
0 Kudos
Jacob_Williams
New Contributor III
1,678 Views

Thanks Steve!

So, for #4:

Are you saying that if I do require the DLL to redeclare mytype, adding SEQUENCE to both declarations would guarantee that it would be OK, or that it would probably be OK?

If I moved the mytype declaration into a module, what is the best way to provide access to it for the DLL writer?  Is it enough to just give the DLL writer the module sourcefile and they just compile it along with their DLL project?  Or do I need to provide the actual compiled library and mod file that was linked to by the main program?  (or does it not matter either way?).

0 Kudos
Steven_L_Intel1
Employee
1,678 Views

To be legal Fortran for the redeclare, add SEQUENCE. But it will work either way.

You could provide the module source (which presumably has an INTERFACE declaration of the procedures, along with the type), and the user can compile it themselves. The actual library would be compiled into the DLL. 

0 Kudos
Jacob_Williams
New Contributor III
1,678 Views

Thanks!

0 Kudos
IanH
Honored Contributor III
1,678 Views

Steve Lionel (Intel) wrote:
You could provide the module source (which presumably has an INTERFACE declaration of the procedures, along with the type), and the user can compile it themselves. The actual library would be compiled into the DLL.

Isn't there the potential, with this approach, that different compilation options used between the DLL supplier and the client could result in incompatibilities in the low level interface of the procedure?

Does this potential exist still exist if a precompiled mod file is supplied, or is the information transmitted in the mod file robust to changes in compilation options?

(Considering compile options here like changes in the default real kind or changes in structure alignment.)

0 Kudos
Steven_L_Intel1
Employee
1,678 Views

True - if the module sources are compiled with nondefault options, this could be an issue. So to eliminate that, make sure you explicitly specify the kinds of all variables and add "!DEC$ ATTRIBUTES DEFAULT :: name" to each procedure interface block.

0 Kudos
Izaak_Beekman
New Contributor II
1,678 Views

Sorry, but can you explain what the directive does? And where in the procedure interface block does the directive go? A small 2-3 line example might help me understand this better.

OK, I think I understand this now… Will this matter for logical and character variables or just integer, real and complex variables?

0 Kudos
Steven_L_Intel1
Employee
1,678 Views

All variables of intrinsic type other than character, so yes, logical too.

0 Kudos
Jacob_Williams
New Contributor III
1,678 Views

Should I be concerned about warning #6379: "The structure contains one or more misaligned fields" or warning #6380: "The structure length is not a multiple of its largest element; could create misalignments for arrays of this type"?  Adding SEQUENCE seems to cause them.  What are the consequences of misaligned fields?

0 Kudos
Steven_L_Intel1
Employee
1,678 Views

Misaligned fields can reduce performance - that is all. WIthout SEQUENCE, the compiler adds padding to align components. Are you free to rearrange the order of the components in the derived type? Put that integer at the end rather than the beginning, as on x64 the pointer/allocatables are multiples of 8 bytes.

0 Kudos
Jacob_Williams
New Contributor III
1,678 Views

Interesting. I can make the warnings go away by moving the variables around a bit (my actual type is more complicated than the one I posted above).  Thanks again!

0 Kudos
Reply