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

v.b .net 2005 passing array to fortran dll IA32

rezaei
Beginner
657 Views

I have problem with passing array from vb.net 2005 to Fortran Dll. The vb and FORTRAN codes that I write are:

Public Class Form1

Declare Auto Function fa Lib "H:\Codes\VB .net\fa\Debug\fa" (ByRef Barray As Single) As Single

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim fff As Single

Dim barray(0 To 3, 0 To 7) As Single

fff = fa(barray(0, 0))

TextBox1.Text = fff.ToString

End Sub

End Class

function Farray(arr)

!DEC$ ATTRIBUTES DLLEXPORT,STDCALL,REFERENCE,ALIAS:"Farray" :: Farray

REAL arr(1:3,1:7),Farray

Farray=5.

return

end

In FORTRAN help we can see using of "Option base 1" command, but in vb.net 2005 this command is not supported.

The error of program is such as this " Unable to find an entry point named 'fa' in DLL 'H:\Codes\VB .net\fa\Debug\fa'."

Sincerely yours

Behnam Rezaei

0 Kudos
1 Solution
ArturGuzik
Valued Contributor I
657 Views

Behnam,

the error message tells you that the function can't be found in your dll. This is not a surprise, as you exported

....,ALIAS:"Farray" :: Farray

while trying to load

Declare Auto Function fa Lib ....

You need to adjust one side or the other. Then you'll face a real problem, that is, passing array. Please search this Forum for (many) similar threads ragarding the issue (you can use SafeArrays, see example in your install IVF directory, or pass number of elements and address of first element).

If you need (?) to change VB to non-zero based index, you can use Array.CreateInstance method (example in Programming Microsoft Visual Basic .Net, by F. Balena or try to find example on the Internet).

A.

View solution in original post

0 Kudos
3 Replies
ArturGuzik
Valued Contributor I
658 Views

Behnam,

the error message tells you that the function can't be found in your dll. This is not a surprise, as you exported

....,ALIAS:"Farray" :: Farray

while trying to load

Declare Auto Function fa Lib ....

You need to adjust one side or the other. Then you'll face a real problem, that is, passing array. Please search this Forum for (many) similar threads ragarding the issue (you can use SafeArrays, see example in your install IVF directory, or pass number of elements and address of first element).

If you need (?) to change VB to non-zero based index, you can use Array.CreateInstance method (example in Programming Microsoft Visual Basic .Net, by F. Balena or try to find example on the Internet).

A.

0 Kudos
anthonyrichards
New Contributor III
657 Views
Here is some help taken from http://www.codeguru.com/vb/gen/vb_misc/algorithms/article.php/c7495 :

quote:

Arrays
An array in VB is implemented as a "SafeArray." This means that you can use some of the API calls to access certain bit and pieces of the array that are otherwise inaccessible. A SafeArray contains 20 bytes of memory, plus 8 bytes per dimension, plus the memory required to store the data.

Note: There is an error in the MSDN. It states that an additional 4-bytes per dimension are required. It should read 8 bytes.
For example, consider an array defined using the following statement:

Dim arr_intTemp(4)(3) As Integer

This will have 20 bytes,

Plus 8 for each dimension, another 16 bytes,

Plus 12 (4x3) Integers of 2 bytes each, 24 bytes,

Giving a total size of 60 bytes for the array.

The safe array can basically be divided into three sections. The first is the safe array pointer, the second the "base" of the array, and the third the data area of the array.

The Safe Array Pointer
The safe array pointer is a pointer (4 bytes) that points to the base of the safe array. The location of this pointer remains fixed at all times; however, the locations of the "base" change each time the array is redimensioned (Redim).

The Array "Base"
The base of the array is defined as follows (each block represents a byte):

Name Bytes Description

cDim 2 A count of the number of dimensions in the array.
fFeature 2 Flags
cbElements 4 Size of each element in the array.
cLocks 4 Used to lock the array.
pvData 4 A pointer to the first data element in the array.
rgsabound 8 * cDim Safe_Array_Bound array.

cDim contains the number of dimensions that the array has. So, for example, a VB array defined using the code:

Dim arr_intTemp(4, 3) As Integer

cDim contains the value 2.

The fFeature flags may be any combination of the following:

Name Hexadecimal Value Description

FADF_AUTO 0x0001 Array is allocated on the stack.
FADF_STATIC 0x0002 Array is statically allocated.
FADF_EMBEDDED 0x0004 Array is embedded in a structure.
FADF_FIXEDSIZE 0x0010 Array may not be resized or reallocated.
FADF_BSTR 0x0100 An array of BSTRs.
FADF_UNKNOWN 0x0200 An array of IUnknown*.
FADF_DISPATCH 0x0400 An array of IDispatch*.
FADF_VARIANT 0x0800 An array of VARIANTs.
FADF_RESERVED 0xF0E8 Bits reserved for future use.

cbElements contains the size (in bytes) of the elements in the array.

Note: If the elements are pointers (for example, for strings) the cbElements only records the length of the pointer, not the entire data structure.
cLocks contains the number of times the array has been locked without corresponding unlock.

pvData is a pointer to the first element of data in the array.

rgsabound is an array of elements of type Safe_Array_Bound, and contains the bounds data for each dimension of the safe array. The rgsabound array is stored with the right-most dimension in rgsabound[0] and the left-most dimension in rgsabound[cDim . 1] (in other words, there is one Safe_Array_Bound element for each dimension in the array). The Safe_Array_Bound element is 8 bytes big and is allocated as follows:

Name Bytes Description

cElements 4 The number of elements in the dimension.
lLbound 4 The lower bound of the dimension.

So, for the array defined as:

Dim arr_intTemp(4, 3) As Integer

rgsabound will contain 2 elements. The first (element 0) will has cElements = 5 and lLbound = 0, whereas the second (element 1) has cElements = 3 and lLbound = 0.

The Data Area
The data array is simply a sequence of elements of the array. It therefore has a size of N * m, where N is the number of elements in the array and m is the size of each element in the array. It should be noted that, for an array of strings or objects, only the pointer is stored in the arrays data sequence (in other words, m equals 4 bytes, the size of a pointer). The data is stored in such a way that the first dimension is stored first, then the second, and so on.

Example of VB Array Storage
Consider a VB array defined with the following code:

Dim arr_intTemp(0 to 1, 1 to 2) As Integer

arr_intTemp(0, 1) = 1
arr_intTemp(0, 2) = 2
arr_intTemp(1, 1) = 3
arr_intTemp(1, 2) = 4
Will be stored as follows (each block is a byte):

Remember that the bytes occur in little-endian format.

Unquote

(for the rest of the guide see the link above)
0 Kudos
Steven_L_Intel1
Employee
657 Views
IVF has routines for manipulating SafeArrays, and a sample is provided, but in many cases you don't need to go to that effort - just pass the first element of the VB array and accept it as a normal Fortran array. You can declare fortran arrays with 0 origin too. I don't remember offhand if one might need to use ByVal on the VB side.
0 Kudos
Reply