3

我正在尝试编译一个共享对象(最终在 Python 中与 ctypes 一起使用)。用于构建对象的命令行是:

gcc -Wall -O3 -shared -Wl,-soname,borg_stream -lm -m128bit-long-double -fPIC \
    -D_FILE_OFFSET_BITS=64 -o borg_stream.so data_stream.c data_types.c \
    file_operations.c float_half.c channels.c statistics.c index_stream.c helpers.c

该库在 32 位操作系统上正确构建,它可以满足小文件的需要。但是,对于大于 4GB 的文件,它无法通过单元测试。此外,它在执行 fseek/ftell 时将 errno 设置为 EOVERFLOW。但是,如果我 printf sizeof(off_t),它会返回 8。如果我删除-D_FILE_OFFSET_BITS=64,那么它会打印 4。所以它似乎-D_FILE_OFFSET_BITS正在正确地完成它的工作。

为什么大文件支持仍然不起作用?我究竟做错了什么?

4

3 回答 3

5

将选项添加-D_LARGE_FILE_SOURCE=1到 gcc 编译。

fseek64()是一个 C 函数。要使其可用,您必须_FILE_OFFSET_BITS=64在包含系统标题之前进行定义。这将或多或少定义fseek为实际行为fseek64。或者您可以在编译器参数中执行此操作,例如gcc -D_FILE_OFFSET_BITS=64,您已经在执行此操作。

http://www.suse.de/~aj/linux_lfs.html有一个很好的关于 linux 上大文件支持的信息:

用 . 编译你的程序gcc -D_FILE_OFFSET_BITS=64。这会强制所有文件访问调用使用 64 位变体。几种类型也发生变化,例如off_t变为off64_t。因此,重要的是始终使用正确的类型,int而不是off_t在 C 代码中使用 eg。为了与其他平台的可移植性,您应该使用getconf LFS_CFLAGS它将-D_FILE_OFFSET_BITS=64在 Linux 平台上返回,但可能会在其他平台上返回,例如在 Solaris 上。对于链接,您应该使用通过报告的链接标志getconf LFS_LDFLAGS。在 Linux 系统上,您不需要特殊的链接标志。定义_LARGEFILE_SOURCE_LARGEFILE64_SOURCE。通过这些定义,您可以open64直接使用 LFS 函数。使用O_LARGEFILE带有 open 的标志来操作大文件。

希望这可以帮助。

于 2013-01-26T06:32:00.577 回答
4

使用 fseeko 和 ftello。不是 fseek 和 ftell。当然不是任何名称中包含 64 的函数。

于 2013-01-26T06:40:51.253 回答
2

fseek()ftell()接受一个int32 位的,所以它被强制转换并且你失去了处理大于 4GB 的地址空间的能力。而是使用fseeko64()and ftello64()which 采取long.

于 2013-01-26T04:46:08.507 回答