1
votes

I have a C file pointer which I must pass to a Fortran77 program (as an integer) only to be used back again in the C program (as a file pointer) for writing more data into a text file. My C skills are outdated since I have forgotten most of it. Can anyone tell me how to convert a C FILE pointer into an integer and back? I would appreciate your help.

I am maintaining a legacy code that just worked fine (by accident) a 10 year old compiler. I am having problems porting the code. The new compilers are the intel C and Fortran compilers.

I know Fortran 2003 provides ISO bindings for C but I cannot use them here for other reasons.

3
Are you looking for a file descriptor, as the two current answers suggest, or are you looking to just treat the pointer address literally as an integer directly? - Jim Buck
If the latter, how many bytes are a pointer and integer on your platform? If an integer is big enough to hold the point, just cast the pointer using intptr_t or uintptr_t. - Jim Buck
The machine is 64 bit. Treating the pointer address as an integer would also do the trick though. I just need a way to keep track of an open file when the program gets back into C. I do not know how to get it back. Can you write how to do that as an answer? I would be willing to upvote it. - Corrupted MyStack
Done. Added an answer discussing this method. - Jim Buck

3 Answers

3
votes

From FILE * to int

int fildes = fileno(f);

From int to FILE *:

FILE *f = fdopen(fildes, "r+");
1
votes
  1. Converting a file pointer to an int ( file descriptor )

int fileno(FILE *stream); The function fileno() examines the argument stream and returns its integer descriptor.

2.Converting a file descriptor to a file pointer

FILE *fdopen(int fildes, const char *mode); The fdopen function associates a stream with a file descriptor.

1
votes

I'm not sure if doing a fopen/fileno/fdopen sequence would "keep a file open" as you would expect (as the currently-marked answer would suggest). Or maybe that's platform-dependent so that you can't depend on it either way.

To do what you want without any doubt about this, just simply use a uintptr_t to assign your FILE * to, pass it to your Fortran code (assuming it can handle whatever size uintptr_t is on your platform [which you say is 64 bits in a comment on your OP]), then when Fortran passes it back to you, assign/cast your uintptr_t back to your FILE *, and happily use all the file functions with it.