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.