C-Fortran Interface

This is a discussion on C-Fortran Interface within the C Programming forums, part of the General Programming Boards category; I am writing a program in Fortran and C. I have a pointer to an array in C, and I ...

  1. #1
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40

    C-Fortran Interface

    I am writing a program in Fortran and C. I have a pointer to an array in C, and I have a Fortran subroutine that needs to access the array. My Fortran variable is declared as

    Code:
    INTEGER, DIMENSION(:), POINTER :: A
    And I would like to call a C function getArrayPtr(long*) to do something like

    Code:
    A => getArrayPtr(i) ! i is the index into my list of pointers
    How would I go about doing this? Thank you.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Generally (assuming a gcc toolchain?) C function names get mangled by prefixing an underscore. So something like _getArrayPtr(i) may work.

  3. #3
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    I'm using the Intel compilers. Name mangling is not a problem - I've already called several functions/subroutines going both directions. The problem is passing not only a pointer, but a pointer to an array (of any size), getting Fortran to know it is associated, what the C argument should really be, etc.

    I have allocated an array in Fortran and passed it to a C function to print the values (successfully). I have also allocated memory in C and given Fortran the pointer, assigned values in Fortran, and tried to print the values (using the same function as before) from C, but the data gets corrupted as soon as I make the call to print). Immediately before the print call, I can see (Totalview debugger) that the values are correct (and correctly spaced/4 bytes per element), but as soon as the call takes place, everything is ruined, even if I look at the values from the Fortran side. The first element in the array is correct, but everything after that is changed.

    I will post my current code when I get to work tomorrow.
    Last edited by ldb88; 08-12-2009 at 07:49 PM.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by ldb88 View Post
    I'm using the Intel compilers. Name mangling is not a problem - I've already called several functions/subroutines going both directions. The problem is passing not only a pointer, but a pointer to an array (of any size), getting Fortran to know it is associated, what the C argument should really be, etc.

    I have allocated an array in Fortran and passed it to a C function to print the values (successfully). I have also allocated memory in C and given Fortran the pointer, assigned values in Fortran, and tried to print the values (using the same function as before) from C, but the data gets corrupted as soon as I make the call to print). Immediately before the print call, I can see (Totalview debugger) that the values are correct (and correctly spaced/4 bytes per element), but as soon as the call takes place, everything is ruined, even if I look at the values from the Fortran side. The first element in the array is correct, but everything after that is changed.

    I will post my current code when I get to work tomorrow.
    Fortran treats arrays in column-major order. (At least that might explain why you're not seeing what you expect to see where you are seeing it. If you're getting total garbage, then that doesn't help.)

  5. #5
    cout << "Bye World!";
    Join Date
    Jun 2006
    Posts
    40
    I think column-major vs. row-major would only become a problem if the array were multidimensional. However, this is just a 1d array.

    c.h
    Code:
    #ifndef C_H
    #define C_H
    
    #define cFunc cfunc_
    #define cAllocArray callocarray_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
      void cFunc(long *, long *);
      void cAllocArray(long *, long *);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    c.c
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "c.h"
    
    void cFunc(long *A, long *size) {
      int i;
      for(i=0; i < *size; i++) {
        printf("A[%d] = %d\n", i, A[i]);
      }
    }
    
    void cAllocArray(long *A, long *size) {
      A = (long*)malloc(sizeof(long)*(*size));
    }
    fort.f
    Code:
    MODULE fort_mod
    
      INTERFACE
        SUBROUTINE cFunc(A, len)
          INTEGER, DIMENSION(*), INTENT(IN) :: A
          INTEGER, INTENT(IN) :: len
        END SUBROUTINE
        SUBROUTINE cAllocArray(A, len)
          INTEGER, DIMENSION(*), TARGET, INTENT(OUT) :: A
          INTEGER, INTENT(IN) :: len
        END SUBROUTINE
      END INTERFACE
    
      CONTAINS
    
      FUNCTION allocArray(len) RESULT(ip)
    
        IMPLICIT NONE
    
        INTEGER, DIMENSION(:), POINTER :: ip
        INTEGER, INTENT(IN) :: len
        INTEGER, DIMENSION(len), TARGET :: A
    
        CALL cAllocArray(A, len)
        ip => A
    
      END FUNCTION
    
    END MODULE fort_mod
    
    PROGRAM main
    
      USE fort_mod
    
      IMPLICIT NONE
    
      INTEGER, DIMENSION(:), POINTER :: A, B
    
      ALLOCATE(A(5))
      A(1) = 5
      A(2) = 4
      A(3) = 3
      A(4) = 2
      A(5) = 1
      CALL cFunc(A, 5)
    
      !CALL cAllocArray(B, 5)
      B => allocArray(5)
      B(1) = 10
      B(2) = 8
      B(3) = 6
      B(4) = 4
      B(5) = 2 ! everything is fine up until here
      CALL cFunc(B, 5) ! here the data is somehow corrupted
    
    END PROGRAM main
    As soon as the call to cFunc takes place, the B array ceases to make sense, even from Fortran.

    Also, if I can get the arguments right, I would like to get rid of the allocArray function. I have seen an example of doing => assignment with a C function, but only with regular pointers, not pointers to arrays.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 06-17-2009, 04:20 PM
  2. real-world apps in C++ (preferably simple)?
    By Aisthesis in forum C++ Programming
    Replies: 13
    Last Post: 06-12-2009, 01:03 PM
  3. How to get RSSI value, send to sensor, sensor receive package, repackage it?
    By techissue2008 in forum Networking/Device Communication
    Replies: 1
    Last Post: 03-04-2009, 09:13 AM
  4. Calling IRichEditOle interface methods
    By Niara in forum C Programming
    Replies: 2
    Last Post: 01-16-2009, 12:23 PM
  5. OOP in C
    By lyx in forum C Programming
    Replies: 4
    Last Post: 11-23-2003, 12:12 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21