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

Passing Numeric SafeArray from VB.Net to FORTRAN

Bruce_Barker
Beginner
563 Views

Hello,

I'm trying to modify the Safearray example for passing multi-dimensional string arrays from VB.Net to Fortran. I want to be able to pass large REAL*8 arrays using Safearray. I have a program that exceeds the stack storage to due large array sizes and I want to pass them using Safearrays. I modified the example but I can't seem to get SafeArrayGetElement statement to retrieve values from the passed in array.  The code below shows the VB calling routine with the FORTRAN routine below. SafeArrayGetElement returns 0 for the array index provided. I intend to use a pointer to CurElem to get the value and work on it.

Any help would be appreciated.

Imports System.Runtime.InteropServices ' Required for using MarshalAs
Public Class Form1

    ' Declare the Fortran routine.  The name of the routine is case-sensitive
    ' and the path to the DLL is explicit.  When run from Visual Studio, the DLL
    ' is looked for in the BIN subfolder of the VB.NET project
    '
    ' By default, VB.NET would simply pass the data to the DLL without any bounds
    ' information (and no chance of rewriting the strings).  So we use the MarshalAs
    ' attribute to tell it to pass a SafeArray.  If you were passing numeric types,
    ' you could just pass the data and access it as a normal array.
    '
    Private Declare Sub ForCall Lib "SafeArrayFORTRAN.dll" _
     (<MarshalAs(UnmanagedType.SafeArray)> ByRef array1(,) As Double)

    Private myarray(2, 3) As Double
    Private Sub _cmdRun_Click(sender As Object, e As EventArgs) Handles _cmdRun.Click
        myarray(0, 0) = 12
        myarray(0, 1) = 11
        myarray(0, 2) = 10
        myarray(0, 3) = 9
        myarray(1, 0) = 8
        myarray(1, 1) = 7
        myarray(1, 2) = 6
        myarray(1, 3) = 5
        myarray(2, 0) = 4
        myarray(2, 1) = 3
        myarray(2, 2) = 2
        myarray(2, 3) = 1

        Call ForCall(myarray)

    End Sub
End Class


      Subroutine ForCall(VBArray)
!DEC$ ATTRIBUTES DLLEXPORT,REFERENCE,STDCALL::ForCall
!DEC$ ATTRIBUTES ALIAS: 'ForCall'::ForCall
!DEC$ ATTRIBUTES REFERENCE :: VBArray
      use ifcom ! Declare SafeArray and BSTR interfaces

      implicit none
  
      integer(int_ptr_kind()), intent(inout) :: VBArray  !Pointer to a SafeArray structure  
      INTEGER(INT_PTR_KIND()) :: ptrElem
      REAL*8,TARGET :: CurElem
      POINTER(ptrElem, CurElem)  ! This says that ptrElem holds the address of CurElem.     

!> Array in which we will keep track of array bounds
      type bounds_type
        integer lb  ! Lower Bound
        integer ub  ! Upper Bound
      end type bounds_type
 !<    
      integer nbounds  ! Number of bounds
      type(bounds_type), allocatable :: bounds(:)
      integer, allocatable :: indexes(:)  ! Array to hold current element indexes
      
      integer :: i, j, iRes
      nbounds = SafeArrayGetDim (VBArray)
      allocate (bounds(nbounds), indexes(nbounds))
      
      do i=1,nbounds
        ires = SafeArrayGetLbound (VBArray, i, bounds(i)%lb)
        ires = SafeArrayGetUbound (VBArray, i, bounds(i)%ub)
      end do
      
      DO j=bounds(1)%lb,bounds(1)%ub 
        DO i=bounds(2)%lb,bounds(2)%ub
          indexes(1)=i+1
          indexes(2)=j+1
          ires = SafeArrayGetElement (VBArray, indexes(1), loc(ptrElem))
          !OUTPUT CurElem HERE
        end do
      end do
      deallocate (bounds)
      deallocate (indexes)
  
      return  
      end subroutine ForCall

 

0 Kudos
3 Replies
Bruce_Barker
Beginner
563 Views

Also, is there a comprehensive reference on calling SafeArrays from Intel Fortran. i couldn't find much in the way of documentation on the topic.

Thanks!

0 Kudos
Bruce_Barker
Beginner
563 Views

Ok, I found the solution to my original problem, which was a Stack Overflow Exception when passing large arrays to my FORTRAN dll. I was trying to correct the issue by passing SafeArrays. A much simpler approach is to change the Heap Array parameter to 0. The answer came from here: https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/279050

 

0 Kudos
Kevin_D_Intel
Employee
563 Views

Glad you found a solution. Thank you for sharing your findings/solution also.

0 Kudos
Reply