- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Glad you found a solution. Thank you for sharing your findings/solution also.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page