2011-04-11 77 views
3

我正在设计C库,它进行一些数学计算。我需要指定序列化接口才能保存并加载一些数据。问题是,在库的公共API中使用FILE *指针是否正确(从二进制兼容的角度)?文件的二进制兼容性*

目标platfoms是:

  • 于Linux x86,x86_64的用gcc> = 3.4.6
  • 的Windows的x86,x86_64的> = WinXP中使用VS> = 2008sp1

我需要尽可能多的二进制兼容,因此目前我的变种是如下:

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

所以我很好奇如果正确使用FILE *或更好地切换到wchar */char *?

+0

我终于决定使用文件描述符,因为能够从python和matlab脚本中使用这个库是很重要的。这两种语言都提供了fd而不是FILE *。所以我决定使用它,尽管fileno不在c标准中。 – prokher 2011-04-20 20:14:37

+0

发生了另一个问题:AFAIK使用文件描述符和FILE *是不正确的,如果它是使用静态C运行时(使用/ MT,/ MTd) - [msdn-link](http:/ /msdn.microsoft.com/en-us/library/ms235460%28v=vs.80%29.aspx)。我很困惑。我真的不想在API中使用文件名,因为它只会将使用限制在磁盘上。相反,使用fd或FILE *可以指定任何流,但静态CRT并非如此。我被卡住了。 ( – prokher 2011-04-23 10:30:21

回答

4

我不同意ThiefMaster:当存在一个等效的便携式解决方案时,在本地使用(例如,在Linux上使用int类型的文件描述符以及在窗口上使用类型为void *的句柄)没有任何好处。

我可能会用FILE *而不是从库中按名称打开文件:它可能对图书馆用户来说更麻烦,但它也更灵活,因为大多数libc实现提供了各种文件打开方式( fopen(),_wfopen(),_fdopen(),fdopen(),fmemopen(),...),你不必自己维护独立的宽字符API。

+0

是的,这是为了避免维护单独的宽字符版本。谢谢。 – prokher 2011-04-11 15:11:00

2

我既不使用,但让用户通过文件描述符作为int

然后你可以fdopen()它在你的代码中得到FILE*

但是,使用Windows时,它可能不是最好的解决方案,即使它确实有一些帮助函数来获取数字文件描述符。


然而,传递FILE*const char*要细,太。如果库需要打开/关闭文件,我宁愿传递一个文件名,因为它的代码少。

+0

)文件描述符和'FILE *'在这个用例中大部分是可以互换的,因为你总是可以通过'fdopen()'和'fileno()'获得另一个;但是,其中只有一个是C标准库,我很好奇为什么会选择不太便携的解决方案? – Christoph 2011-04-11 13:22:28

+0

通过'FILE *'选择文件描述符有几个很好的理由:当你需要能够从IO错误中恢复时,当你想要做非阻塞的IO或者控制你的程序何时会被阻塞,或者当你需要确保当另一个进程/程序继承一个打开的文件时,在你的缓冲区中没有任何输入会丢失,这些似乎都不适用,所以我会使用'FILE *'。 – 2011-04-11 14:28:56

+0

实际上,我终于决定使用文件描述符,因为能够在python和matlab脚本中使用这个库是非常重要的,这两种语言都提供了fd而不是FILE *。决定使用它,尽管f行事fileno不在c标准。 – prokher 2011-04-13 07:10:59

1

是的,从稳定的二进制接口角度来看,在这里使用FILE *是正确的。我想你可能会把这个与使用FILE而不是指向它的指针混淆起来。请注意,标准库的fopen,fgets等函数都使用(作为参数和返回值)FILE *类型作为其公共接口的一部分。

0

A FILE *是标准的ANSI/ISO C89和C99(甚至K & R)型。这是一个可移植的梦想,我更喜欢它。你可以安全地使用它。它不会比这更好。