1

I am doing some mixed programming between C++ and FORTRAN. A problem comes up about passing a character array from FORTRAN to C++ as shown in the code.

CDll.h:

// CDll.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif

#define DLLEXPORT __declspec(dllexport)

DLLEXPORT void testchararray(char arr[][10]);

#ifdef __cplusplus
}
#endif

CDll.cpp:

// CDll.cpp
#ifndef __cplusplus
#define __cplusplus
#endif

#include "CDll.h"
#include <iostream>

using namespace std;

void testchararray(char arr[][10])
{
    cout << arr << endl;
}

FMain.f90:

!DIR$ OBJCOMMENT LIB: "CDll.lib"
MODULE FModule
    IMPLICIT NONE

    INTERFACE

        SUBROUTINE testchararray(arr)
        !DIR$ ATTRIBUTES C, ALIAS: "testchararray" :: testchararray
            CHARACTER(10), DIMENSION(:), INTENT(IN) :: arr
            !DIR$ ATTRIBUTES REFERENCE :: arr ! <-- If the way is right, is the directive nessary to add ?
        END SUBROUTINE testchararray

    END INTERFACE

END MODULE FModule

PROGRAM Main
    USE FModule
    IMPLICIT NONE

    character(10), dimension(2) :: arr = ["1234567890", "0987654321"]

    write(*,"(Z)") loc(arr)
    call testchararray(arr)

END PROGRAM Main

CDll.h and CDll.cpp are generated into DLL and linked by FORTRAN main program.

The memory addresses before and after calling the subroutine are not consistent to each other thus the character array is not properly passed. Am I doing it the wrong way or is there anything I have not yet noticed ? Thanks for any help.

PS: The project was debugged on x64 platform.

Blane John
  • 65
  • 6
  • 1
    I don't understand why you use the reference attribute directive. It is unnecessary if not even harmful. Ayway the moder way to bind Fortran (not spelled FORTRAN since 1990) and C (or C++) is using [tag:fortran-iso-c-binding]. Please tell us what exactly is happening. How does the output look like? Which addresses do not conform? How do you get those addresses?See [ask]. – Vladimir F Героям слава Apr 19 '18 at 11:15
  • Thanks Vladimir. In the Main program of Fortran, the address (lets say addr1) of array arr is queried before the call. And then in the call, the C++ testchararray function prints out the address (say addr2) of dummy arr. addr1 and addr2 are supposed to be consistant but they are not maybe due to my way of passing character array from Fortran to C++ is not correct. So how can I do it correctly? – Blane John Apr 19 '18 at 12:18
  • We have many similar questions here. Really loads. I can't be asked to write a full tutorial again, sorry. Start reading in the tag I linked. One thing is clear now, you are using an assumed shape array `DIMENSION(:)`, that can't possibly work. It must be an assumed size `(*)` or explicit size `(n)` array and you will have to pass the size somehow. If you asked why is your approach wrong I can easily answer, but write a full solution - no, we have too many similar questions here to waste the time again. Maybe someone else. – Vladimir F Героям слава Apr 19 '18 at 12:41
  • OK, I'll try first. – Blane John Apr 19 '18 at 12:49

0 Answers0