Quantcast
Channel: Intel® Software - Intel® Visual Fortran Compiler for Windows*
Viewing all articles
Browse latest Browse all 5691

Program triggering a breakpoint when exiting a function that convert 2-d char array from C to Fortran

$
0
0

I have a Fortran program that talks to a dll that is written in C++. The Fortran program is crashing on Windows only when it comes out of the function given below. It works fine in Linux and Mac OS.

 

  interface
    function GetResultNamesFortran (dmy_strResultArray) result (intSuccess)
       character (len=*), dimension (:), allocatable, intent (inout) :: dmy_strResultArray
       integer (kind=4) :: intSuccess
    end function GetResultNamesFortran
  end interface

  

  function GetResultNames (this, dmy_strResultArray) result (intSuccess)

    implicit none
  
    class (FunctionalModuleInterface),             intent (inout) :: this
    character (len=*), dimension (:), allocatable, intent (inout) :: dmy_strResultArray
    integer (kind=4) :: intSuccess
    
    ! Local Variables
    integer (kind=4) :: intCount
    integer (kind=4) :: intStat
    integer (kind=4) :: i
    integer (kind=4) :: j
    type (C_PTR)     :: ptrPrimary = C_NULL_PTR
    type (C_PTR), dimension (:), allocatable :: ptrArray
    character (len=LEN (dmy_strResultArray)), pointer :: strCharPointer
    
    ! Initialize Variables
    intSuccess = -1
    
    ! Make sure we call the right function.  
    FindFirstAssociatedFunctionPointer : &
    if (ASSOCIATED (this%GetResultNamesFortran)) then
    
      ! Pass the tag list onto the plugin
      intSuccess = this%GetResultNamesFortran (dmy_strResultArray)
      
    else if (ASSOCIATED (this%GetResultNamesCpp)) then
  
      ! Call the C++ function and get the pointer to the array of character arrays
      intSuccess = this%GetResultNamesCpp (intCount, ptrPrimary)

      ! Allocate an array of C_PTRs based on the number of results
      ALLOCATE (ptrArray(intCount), STAT=intStat)
      
      ! Total the success of operations
      intSuccess = intSuccess + intStat
      
      ! Allocate the fortran return array to the appropriate size
      ALLOCATE (dmy_strResultArray(intCount), STAT=intStat)

      ! Total the success of operations
      intSuccess = intSuccess + intStat

      ! Continue if the allocations were successful
      WasAllocated : &
      if (intSuccess .eq. 0) then

        ! Blank the array of names first
        dmy_strResultArray = ""      
        ! Convert the pointer to an array of pointers
        call C_F_POINTER (CPTR=ptrPrimary, FPTR=ptrArray, SHAPE=[intCount])

        ! Loop over the array of C pointers
        PointerLoop : &
        do i =1, intCount
        
          ! Convert the ith pointer to a fortran character pointer
          call C_F_POINTER (CPTR=ptrArray(i), FPTR=strCharPointer)

          ! Convert the C character array to a Fortran character array
          ConvertChars : &
          do j = 1, LEN (dmy_strResultArray)

            ! If the character in the C string is a null character we have reached the
            ! end and can exit.
            if (strCharPointer(j:j) .eq. C_NULL_CHAR) then
            
              ! Exit the do loop that is converting C characters to Fortran characters
              exit

            else
            
              ! Convert the ith character from the C character to the Fortran string.
              dmy_strResultArray(i)(j:j) = strCharPointer(j:j)
              
            end if
            
          end do ConvertChars

        end do PointerLoop
        
      end if WasAllocated
    
    end if FindFirstAssociatedFunctionPointer
  
  end function GetResultNames

 

Below is the C++ function that is in the DLL written in C++. This function is called properly and comes back to the above Fortran code with proper character arrays populated.

 int GetResultNames (int *dmy_intCount, char **&dmy_strResults) {

    // Return variable
    int intSuccess = -1;

    // If the incoming character array is already allocated { deallocate it
    if (dmy_strResults != NULL ) {

      // Deallocate the character array
      delete[] dmy_strResults;

    }

    // Allocate the character array to the number of results
    dmy_strResults = new char *[intM_NUMBER_OF_RESULTS];

    // Set the result names
    dmy_strResults[0] = (char *) "CppResult1";
    dmy_strResults[1] = (char *) "CppResult2";
    
    *dmy_intCount = intM_NUMBER_OF_RESULTS;

    // Return the success of the operation
    intSuccess = 0;

    return intSuccess;
    
  }

The problem I am having right now is that when the program comes out of the Fortran function shown above, Visual Studio shows "The program has triggered a breakpoint."

I have added return at various places in the Fortran function. What interesting thing I found out is that if I return after C_F_POINTER line, then the program complains for the triggering of breakpoint.

        ! Convert the pointer to an array of pointers
        call C_F_POINTER (CPTR=ptrPrimary, FPTR=ptrArray, SHAPE=[intCount])

So the problem is somewhere the use of C_F_POINTER in an improper way. Can you help me in figuring out what really is causing the program to abort. Again, it works fine on Linux and Mac. Only the problem is showing up on Windows.
 

 


Viewing all articles
Browse latest Browse all 5691

Trending Articles



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