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

SafeArrayGetElement isn't getting anything

Isaac_V_1
Beginner
642 Views

Greetings, dear fellow developers!

I have been doing some programming with mixed languages (VSTO, VBA for Excel(R) + Fortran) for almost 2 years and I hadn't needed to use Safe Arrays. Everything had worked well by just passing little arrays to my Fortran DLLs. However, this time I have been working on a big DLL that needs big multidimensional arrays, that was when I had to start using Safe Arrays... I started trying to re-write Mr. Lionel's Safe Arrays example just for practice (and to see if I am getting the idea)... But it's not working! My code is this

      SUBROUTINE elSeguro(refCp)
      !DEC$ ATTRIBUTES DLLEXPORT, STDCALL, DECORATE :: ELSEGURO
      !DEC$ ATTRIBUTES ALIAS : 'ELSEGURO' :: ELSEGURO
      !DEC$ ATTRIBUTES REFERENCE :: refCp
          USE ifcom
          IMPLICIT NONE
          
          !Parámetros
          INTEGER, PARAMETER :: DP = KIND(1.D0)
          
          !Punteros
          INTEGER(INT_PTR_KIND()),INTENT(INOUT) :: refCp
          
          TYPE limtip
              INTEGER Linf
              INTEGER Lsup
          ENDTYPE limtip
          
          INTEGER nlimts
          TYPE(limtip),ALLOCATABLE,DIMENSION(:) :: limtes
          INTEGER, ALLOCATABLE, DIMENSION(:) :: indces
          
          INTEGER(INT_PTR_KIND()) :: ptrDoble
          REAL(DP), TARGET :: elDoble
          
          INTEGER :: i, iRes, longtd
          nlimts = SafeArrayGetDim(refCp)
          ALLOCATE(limtes(nlimts), indces(nlimts))
          
          DO i=1, nlimts
              iRes = SafeArrayGetLbound(refCp, i, limtes(i)%Linf)
              iRes = SafeArrayGetUbound(refCp, i, limtes(i)%Lsup)
          ENDDO
          
          OPEN(UNIT=1,FILE="arregloSeguros.txt",STATUS="UNKNOWN")
              WRITE(1,*) "Forma del arreglo pasado por VB:"
              WRITE(1,'("  (")',ADVANCE='NO')
              DO i=1, nlimts
                  WRITE(1,'(I0,":",I0)',ADVANCE='NO') limtes(i)
                  IF (i<nlimts) WRITE (1,'(",")',ADVANCE='NO')
              ENDDO
              WRITE(1,'(")")')
              
              WRITE(1,*) "Contenido de los arreglos:"
              
              indces = limtes%Linf
              loopLeer: DO
                  WRITE(1,*) "Hola"
                  iRes = SafeArrayGetElement(refCp, indces(1), loc(ptrDoble))
                  elDoble = ptrDoble
                  
                  WRITE(1, '("  A(")', ADVANCE='no')
                  WRITE(1, '(100(I0,:,","))', ADVANCE='no') (indces(i),i=1,nlimts)
                  WRITE(1, '(") = ", F)') elDoble
                  
                  DO i=nlimts, 1, -1
                      indces(i) = indces(i) + 1
                      IF (indces(i) .LE. limtes(i)%Lsup) EXIT
                      indces(i) = limtes(i)%Linf
                      IF (i .EQ. 1) EXIT loopLeer
                  ENDDO
              ENDDO loopLeer
          CLOSE(UNIT=1)
          
          RETURN
      ENDSUBROUTINE

I connected it already with a little VBA Function that passes a 3 row x 6 columns non empty matrix, but when I write (via Fortran) on my *.txt file, even though I have the shape of the arrays, the values of each position are "0.00000".

Please could anyone tell me what is happening there? Thanks in advance

0 Kudos
1 Reply
Steven_L_Intel1
Employee
642 Views
elDoble = ptrDoble

I don't think this does what you want. ptrDoble gets the address of an element as an integer. You are then just assigning it to a double-precision real. The effect of this conversion probably gets you a very small real value that prints as zero.

Try this as a quick approach. Remove the assignment, Add after the declaration of elDoble the following:

pointer (ptrDoble, elDoble)

This says that ptrDoble holds the address of elDoble.

0 Kudos
Reply