3

I am designing C library which does some mathematical calculations. I need to specify serialization interface to be able to save and then load some data. The question is, is it correct (from binary compatibility point of view) to use FILE* pointer in the public API of library?

Target platfoms are:

  • Linux x86, x86_64 with gcc >= 3.4.6
  • Windows x86, x86_64 >= WinXP with VS >= 2008sp1

I need to be as much binary compatible as it possible, so at the moment my variant is the following:

void SMModuleSave(SMModule* module, FILE* dest);
SMModule* SMModuleLoad(FILE* src);

So I am curious if it is correct to use FILE* or better switch to wchar*/char* ?

prokher
  • 490
  • 5
  • 18
  • I've finally decided to use file descriptors cause it is important to be able to use this library from inside python and matlab scripts. Both that languages provide fd but not FILE*. So I've decided to use it in spite of the fact that fileno is not in the c standard. – prokher Apr 20 '11 at 20:14
  • Another problem occurred: AFAIK it is incorrect to use both file descriptor and FILE* if it is the API of dll which has been build with static C runtime (using /MT, /MTd) - [msdn-link](http://msdn.microsoft.com/en-us/library/ms235460%28v=vs.80%29.aspx). I am confused. I don't really want to use filenames in the API cause it will restrict usage to file-on-disk only. On the contrary, using fd or FILE* brings availability to specify any stream, but it is not the case for static CRT. I am stuck. :( – prokher Apr 23 '11 at 10:30

4 Answers4

4

I don't agree with ThiefMaster: there's no benefit in going native (ie using file descriptors of type int on linux and handles of type void * on windows) when there's an equivalent portable solution.

I'd probably go with FILE * instead of opening the files by name from within the library: It might be more of a hassle for library users, but it's also more flexible as most libc implementations provide various ways for file opening (fopen(), _wfopen(), _fdopen(), fdopen(), fmemopen(),...) and you don't have to maintain seperate wide-char APIs yourself.

Christoph
  • 164,997
  • 36
  • 182
  • 240
2

I'd use neither but let the user pass a file descriptor as an int.

Then you can fdopen() it in your code to get a FILE*.

However, when using windows it might not be the best solution even though it does have some helper functions to get a numeric file descriptor.


However, passing a FILE* or a const char* should be fine, too. I'd prefer passing a filename as it's less code to write if a library takes care of opening/closing a file.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • file descriptors and `FILE*` are mostly interchangeable for this use case as you can always get one from the other via `fdopen()` and `fileno()`; however, only one of them is part of the C standard library, and I'm curious why one would choose the less portable solution? – Christoph Apr 11 '11 at 13:22
  • There are several very good reasons to choose file descriptors over `FILE *`: when you need to be able to recover from IO errors, when you want to do nonblocking IO or have control over when your program will block, or when you need to ensure that no input will be lost in your buffer when letting another process/program inherit an open file. None of these seem to apply here, so I would use `FILE *`. – R.. GitHub STOP HELPING ICE Apr 11 '11 at 14:28
  • Actually, I've finally decided to use file descriptors cause it is important to be able to use this library from inside python and matlab scripts. Both that languages provide fd but not FILE*. So I've decided to use it in spite of the fact that fileno is not in the c standard. – prokher Apr 13 '11 at 07:10
1

Yes it is correct, from a stable binary interface perspective, to use FILE * here. I think perhaps you're confusing this with using FILE as opposed to a pointer to it. Notice that your standard library's fopen, fgets, etc. functions all use (both as arguments and return values) the FILE * type as part of their public interfaces.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
0

A FILE * is a standard ANSI/ISO C89 and C99 (even K&R) type. It is a portability dream and I'd prefer it over anything else. You're safe to go with it. It won't get any better than that.

Jens
  • 69,818
  • 15
  • 125
  • 179