2

我需要创建一个应用程序来从 zip 存档中提取一个文件,之后我想为 Android 编译它。

我使用的是 Ubuntu,预装了 libzip-0.10.1。我在 Eclipse 中创建了 C 项目,添加了包含路径并找到了用于提取文件的简单脚本。不幸的是,我无法构建以下内容,我可以使用一些建议。

// zip.c file
#include <stdio.h>
#include <stdlib.h>
#include <zip.h>

int main(int argc, char **argv) {
struct zip *zip_file;
struct zip_file *file_in_zip;
int err;
int files_total;
int file_number;
int r;
char buffer[10000];

if (argc < 3) {
    fprintf(stderr,"usage: %s <zipfile> <fileindex>\n",argv[0]);
    return -1;
};

zip_file = zip_open(argv[1], 0, &err);
if (!zip_file) {
    fprintf(stderr,"Error: can't open file %s\n",argv[1]);
    return -1;
};

file_number = atoi(argv[2]);
files_total = zip_get_num_files(zip_file);
if (file_number > files_total) {
    printf("Error: we have only %d files in ZIP\n",files_total);
    return -1;
};

file_in_zip = zip_fopen_index(zip_file, file_number, 0);
if (file_in_zip) {
    while ( (r = zip_fread(file_in_zip, buffer, sizeof(buffer))) > 0) {
        printf("%s",buffer);
    };
    zip_fclose(file_in_zip);
} else {
    fprintf(stderr,"Error: can't open file %d in zip\n",file_number);
};

zip_close(zip_file);

return 0;
};

我还添加了一些 .h 文件以在我的项目中包含目录,并将一些 .c 文件添加到带有 zip.c 文件的目录中。之后所有的依赖都很好,但我有一个错误:

‘struct zip’ has no member named ‘default_password’ in file zip_fopen_index.c

该文件zip_fopen_index.c是:

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

#include "zipint.h"


ZIP_EXTERN struct zip_file *
zip_fopen_index(struct zip *za, zip_uint64_t fileno, int flags)
{
    return zip_fopen_index_encrypted(za, fileno, flags, za->default_password); // error here
}
4

1 回答 1

3

首先请允许我发表一些评论:

您的程序不是由 Eclipse编译和链接的。

编译由编译器完成(gcc使用选项-c):

make all 
Building file: ../zip.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"zip.d" -MT"zip.d" -o "zip.o" "../zip.c"
Finished building: ../zip.c

链接由链接器完成(通过使用 option 的编译器-o):

Invoking: GCC C Linker
gcc  -o "unzipper"  ./zip.o   
./main.o: In function `zip':
/home/alk/workspace/unzipper/Debug/../zip.c:20: undefined reference to `zip_open'
/home/alk/workspace/unzipper/Debug/../zip.c:27: undefined reference to `zip_get_num_files'
/home/alk/workspace/unzipper/Debug/../zip.c:33: undefined reference to `zip_fopen_index'
/home/alk/workspace/unzipper/Debug/../zip.c:35: undefined reference to `zip_fread'
/home/alk/workspace/unzipper/Debug/../zip.c:38: undefined reference to `zip_fclose'
/home/alk/workspace/unzipper/Debug/../zip.c:43: undefined reference to `zip_close'
collect2: ld returned 1 exit status

Eclipse 提供了一个框架,帮助您管理所有源代码及其引用,同时生成编译器和链接器任务并设置它们的选项。

当链接器在构建程序期间告诉您函数undefined referencezip_*位置时,原因是您没有告诉链接器(通过编译器,通过 Eclipse)zip_*可以在哪里找到这些函数。

这些zip_*函数位于库中,即libzip.

因此,作为程序员,您需要告诉链接器(通过编译器,通过 Eclipse)将这些函数与编译器从您的源代码编译的内容链接起来。

结果,链接器能够从您编译的源代码以及所需的所有库中创建一个可运行的程序。默认情况下,Eclipse(以及链接器)知道某些库,例如包含 C 标准函数的库,即libc.

为了让事情顺利进行:

1 从项目中删除从libzip库的源中提取的源文件。这些源代码已编译到库libzip中,您将在项目中使用它。

2 告诉链接器(通过 Eclipse)libzip用于您的项目。

请按照以下步骤执行此操作:

打开项目的属性

单击“C/C++ 常规”

单击“路径和符号”,在左侧选择“库”选项卡,单击“添加”并输入zip

最后点击“确定”

3 然后尝试构建您的程序:

Building target: unzipper
Invoking: GCC C Linker
gcc  -o "unzipper"  ./zip.o   -lzip
Finished building target: unzipper

(请注意附加选项-lzip!)

如果'libzip'的开发版本之前已经正确安装,你应该没问题。


PS:unzipper是我用于 Eclispe 项目以生成示例的名称。

PSS:我用的是 Eclipse Juno SR1

于 2012-10-18T07:02:00.090 回答