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

assumed shape arrays in a dll

breisfeld
Beginner
933 Views
Hi,
I have written a subroutine in Fortran 90 that I would like to call from VBA in Excel. I would like to use assumed shape arrays for some of the subroutine arguments. However, I have read that to use such arrays I would need to have an explicit interface declared in the calling program. Since the caller is VBA, I presume that this won't work.
Is there a way to use assumed shape arrays without an explicit interface or is there another way around this issue?

Thanks for your help.

-Brad
0 Kudos
5 Replies
Jugoslav_Dujic
Valued Contributor II
933 Views
Quoting - breisfeld
Hi,
I have written a subroutine in Fortran 90 that I would like to call from VBA in Excel. I would like to use assumed shape arrays for some of the subroutine arguments. However, I have read that to use such arrays I would need to have an explicit interface declared in the calling program. Since the caller is VBA, I presume that this won't work.
Is there a way to use assumed shape arrays without an explicit interface or is there another way around this issue?


Short answer: No, not really.

Long answer: assumed-shape arrays are passed by array descriptor. An array descriptor is a structure, which resembles VB SafeArrays (but it's not compatible with them of course). So, in theory, you could declare and manipulate the Fortran array descriptor structure on VB side (it's described in the Intel Fortran help), and pass that to Fortran, but it's more trouble than it's worth.

There's also FOR_DESCRIPTOR_ASSIGN routine, which can help you construct an array descriptor in memory, but I think that it's not directly callable from VBA, since it's __cdecl rather than __stdcall (so you'd have to create a stdcall wrapper).

All in all, I recommend sticking to assumed-size or, better still, explicit-shape arrays.
0 Kudos
Steven_L_Intel1
Employee
933 Views
I would suggest instead what Fortran calls "adjustable arrays". This is where you pass the bounds in as separate arguments. So let's say you had an array that was 100 elements in size. You'd call the Fortran routine sort of like this (I am using Fortran syntax here, but translate appropriately):

call sub(array,100)

On the Fortran side you'd have this:

subroutine sub (array, array_len)
integer, intent(in) :: array_len
real, intent(inout) :: array(1:array_len)

Note that the declaration of the "len" argument as integer, must precede the declaration of the array using that argument. When the routine is entered, the bounds of the array will be taken from the argument. You can pass multiple bounds arguments and use them in bounds expressions if you want.

The reason I prefer adjustable arrays over assumed-size is that this gives the compiler information about the bounds that can then be used in bounds checking, array operations, etc. I'm leery of putting in fixed dimensions unless you know that the array will always be at least that size.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
933 Views
The reason I prefer adjustable arrays over assumed-size is that this gives the compiler information about the bounds that can then be used in bounds checking, array operations, etc. I'm leery of putting in fixed dimensions unless you know that the array will always be at least that size.

We're on the same wavelength actually -- I recommended the "explicit-shape arrays" because I forgot the term "adjustable" (which are a subset of explicit-shape arrays).
0 Kudos
breisfeld
Beginner
933 Views
I would suggest instead what Fortran calls "adjustable arrays". This is where you pass the bounds in as separate arguments. So let's say you had an array that was 100 elements in size. You'd call the Fortran routine sort of like this (I am using Fortran syntax here, but translate appropriately):

call sub(array,100)

On the Fortran side you'd have this:

subroutine sub (array, array_len)
integer, intent(in) :: array_len
real, intent(inout) :: array(1:array_len)

Note that the declaration of the "len" argument as integer, must precede the declaration of the array using that argument. When the routine is entered, the bounds of the array will be taken from the argument. You can pass multiple bounds arguments and use them in bounds expressions if you want.

The reason I prefer adjustable arrays over assumed-size is that this gives the compiler information about the bounds that can then be used in bounds checking, array operations, etc. I'm leery of putting in fixed dimensions unless you know that the array will always be at least that size.

Hi Steve and Jugoslav,

Thank you for the advice. I think that this approach makes sense for my application.

Having returned to Fortran after a few years of using Python, I am having to adjust to the idea that I can't just pass data structures around from function to function without worrying about explicit declarations and things like bounds checking. On the upside, my programs execute _very_ quickly.

-Brad

0 Kudos
Steven_L_Intel1
Employee
933 Views
If you're within Fortran, then it's a lot easier.
0 Kudos
Reply