Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

With iso_c_binding, sending c_ptr to C, malloc,, set value

Question: How do I get the 28 back to Fortran?

main.f90:

       program test

       use play_dice_game
       use iso_c_binding, only : c_ptr, c_f_pointer, c_null_ptr

       type(c_ptr) :: test_ptr
       integer, pointer :: ftest_ptr
       integer result

        test_ptr = c_null_ptr

        result = roll_dice(test_ptr)

        call c_f_pointer(test_ptr, ftest_ptr)

        write(*,*) 'C test pointer is ',test_ptr
        write(*,*) 'Fortran test pointer is ',ftest_ptr

       end program test

play_dice_game.f90:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

       module play_dice_game

       use, intrinsic :: iso_c_binding, only: c_int, c_ptr

       interface
         function roll_dice(test_p) bind(c, name="roll_dice_")
             import :: c_int, c_ptr
             implicit none
             type(c_ptr), intent(out) :: test_p
             integer(c_int) :: roll_dice
         end function
       end interface

       end module play_dice_game

test.c:

#include <stdio.h>
#include <stdlib.h>

int roll_dice_(int *test) {

    if (!*test)
    {
      printf ("Creating storage for test\n");
      test = malloc(sizeof(int));

      *test = 28;
      printf ("variable test is set to %d\n\n",*test);
    }
    else
    {
      printf ("test is not null\n");
    }

    return 0;
}

Compile and Run Program:

  gcc      -g -c test.c             -o test.o 
  gfortran -g -c play_dice_game.f90 -o play_dice_game.o
  gfortran -g -c main.f90           -o main.o
  gfortran -g main.o test.o -o main.exe -lgfortran
  ./main.exe

Output:

Creating storage for test
variable test is set to 28

C test pointer is 0
Fortran test pointer is 0

I tried using c_f_pointer without success. But, if I define in the C file a struct with an int and reference it in the Fortran file I can get the "28" in Fortran. I’d like something simple.

In C:

struct myint {
   int int_tmp;
};

int roll_dice_(struct myint **test) 
...
    *test = malloc(sizeof(**test));
...
    (*test)->int_tmp = 28;

In Fortran:

       type(myint), pointer :: intvar
       call c_f_pointer(myint_ptr, intvar)

       write(*,*) 'my int = ', intvar%int_tmp

>Solution :

I have no idea how fortran works, but your C function has a problem. You allocate memory and then loose the pointer to that memory.

I suggest you take an int ** in roll_dice_ instead to be able to return a pointer to the allocated memory. Example:

#include <stdio.h>
#include <stdlib.h>

int roll_dice_(int **test) {
    if(!test) {
        puts("test is null");
        return 0;             // 0 for fail
    }

    if(!*test) {
        printf("Creating storage for test\n");
        *test = malloc(sizeof **test);

    } else {
        printf("*test is not null\n");
    }

    **test = 28;
    printf("variable test is set to %d\n\n", **test);

    return 1;                 // 1 for success
}

Possible output:

Creating storage for test
variable test is set to 28

 C test pointer is              11640096
 Fortran test pointer is           28
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading