Pass VB 2D array to Fortran DLL

211 views
Skip to first unread message

Ken

unread,
Oct 24, 2006, 3:40:29 PM10/24/06
to gg95
I've seen a couple of references to the subject:

Mike C. 8/20 - Note everything is byRef - the arrays are passed by
referencing the
first element and any 2D basic array must first be changed to a "1D"
array with elements stored in column not row order.

Mike C. 7/28 - I also figured out how to pass a 2D arrays from VB.Net
to FORTRAN and
return the results. What a difference.

Would you be willing to elaborate? Sounds like an 1D array of 1D
arrays? All I've managed so far is to crash VB. Thanks.

Ken

MikeC

unread,
Oct 25, 2006, 5:49:50 AM10/25/06
to gg95
Ken

Here's an example

Dim a(n, n) As Double

Load the values into a(,)

'create a 1D array
Dim a_mod(n * n) As Double

'copy a(,) to a_mod()
'NOTE that address {A(I,J)} = address {A} + (I-1 + n*(J-1))*f
'AND FORTRAN stores elements by column NOT row as in VB
'and LDA is the leading dimension fo matrix a(,)
'
Dim I, J As Integer
'
For J = 1 To N
For I = 1 To LDA
a_mod((J - 1) * LDA + I) = a(I, J)
Next
Next

Then Call FortranDLLProcedure(a_mod(1), etc, etc) ''' Note the 1

On return copy a_mod() back into a(,) if needed

Let me know if anything else needed

Mike C

MikeC

unread,
Oct 25, 2006, 6:22:28 AM10/25/06
to gg95
Ken

Some additional tidbits on passing values. Note that strings are not
included as they are very difficult to pass without problems and I am
still trying to find an easy way to do them

Also note that a Fortran dll object must be placed in the BIN directory
while working
in the development environment. When deployed it must be placed in the
APPLICATION
directory.
'
'Visual Basic.Net Pass
Fortran 77 EQUIV
'
'Boolean ByRef
LOGICAL*2
'Char ByRef
CHARACTER*2
'
'Integer ByRef
INTEGER
'Double ByRef
DOUBLE PRECISION
'
'Integer(*) ByRef Integer(1)
INTEGER(*)
'
'Double(*) ByRef Double(1) DOUBLE
PRECISION(*)
'
'Double(*,*) ByRef Double(1) DOUBLE
PRECISION(#,*) pass as 1D
in column not row order
'

Mike C.

Ken

unread,
Oct 25, 2006, 7:16:44 PM10/25/06
to gg95
Mike,

Thanks for your replies. I'll give it a try. I use VB (VBA, actually)
and not VB.net and am wondering if it might be different. I did a fair
amount of web searching last night and it seems that just passing
a(1,1) would work. I guess I'll try both ways. Your replies are
greatly appreciated.

One other nagging question - in the .def file, why is it necessary to
have 'EXPORTS name=name_' and not just 'EXPORTS name'?

MikeC

unread,
Oct 25, 2006, 10:25:59 PM10/25/06
to gg95
I am not an expert here at all but I believe that the call name inside
the dll has the underscore appended by the compiler

Exports equates the internal procedure name within the dll to the
unscored name referenced with the external call

Suggest you read up on the fortran compiler you are using as to how
internal (within fortran) procedures are named and referenced as
offsets.

Net stores arrays by rows and is zero based whereas Fortran always
stores in column order and everything is referenced as a linear
assembly of numbers. There is no way to pass a 2Dnet array directly.

Not sure what VB6 does but if the array is zero based I doubt it would
work. A(1,1) is just the address of the first element and all other
elements within fortran are computed as a direct offset to the
reference address passed.

Hope this helps

Mike C.

Ken

unread,
Oct 26, 2006, 1:57:26 PM10/26/06
to gg95
Thanks. I think VB6/VBA must be different than VB.net - I tried by
passing a(1,1) and it worked ok. By the way, arrays can be 0 or 1
based in VB6/VBA, though I don't know that it matters. For a 0 based
array, I think a(0,0) would work. Below is the reference on which I
based my test.

I'll give your method a try and see if it works. Thanks again for all
your help!

http://forums.absoft.com/viewtopic.php?pid=1670

Ken

Reply all
Reply to author
Forward
0 new messages