Quantcast
Channel: Recent posts
Viewing all articles
Browse latest Browse all 415

Passing Numeric SafeArray from VB.Net to FORTRAN

$
0
0

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

 


Viewing all articles
Browse latest Browse all 415

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>