繁体   English   中英

C头和源文件混淆

[英]C header and source file confusion

我自己写了一个我想重用的模块。 我的头文件bitstream.h带有结构和函数声明, bitstream.c带有实现。 现在我想在我的其他程序中使用它,但是每次都不需要手动编译bitstream.c ,就像你每次使用它时都不需要编译stdio.h一样,但我不能让它工作。 我的文件看起来像这样:

bitstream.c

#include "bitstream.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

bit_stream_t *fbit_stream(const char *path) {
    FILE *f;

    /* open file for reading */
    f = fopen(path, "rb");

    ...

bitstream.h

#ifndef BITSTREAM_H
#define BITSTREAM_H

#define EOS 0x0a

typedef struct {
    int size;
    int i_byte;
    unsigned char i_bit;
    unsigned char current_bit;
    unsigned char *bytes;
} bit_stream_t;

extern bit_stream_t *fbit_stream(const char *path);
extern unsigned char bit_stream_next(bit_stream_t *bs);
extern void bit_stream_close(bit_stream_t *bs);
extern void print_bit_stream(bit_stream_t *bs);

#endif

我将这两个文件放入/usr/local/include (我在Linux机器上),现在我想在main.c使用它(在其他地方,例如/home/foo/main.c ):

main.c中

#include <bitstream.h>
#include <stdio.h>

int main(int argc, const char *argv[]) {
    if (argc != 2) {
        printf("Need 1 argument!\n");
        return 1;
    }

    bit_stream_t *my_bs;
    my_bs = fbit_stream(argv[1]);

    while (my_bs -> current_bit != EOS) {
        printf("%d", my_bs -> current_bit);
        bit_stream_next(my_bs);
    }

    bit_stream_close(my_bs);
    printf("\n");
    return 0;
}

当我尝试gcc -Wall -o main.o main.c我得到了

/tmp/ccgdq66W.o: In function `main':
main.c:(.text+0x35): Undefined reference to `fbit_stream'
main.c:(.text+0x63): Undefined reference to `bit_stream_next'
main.c:(.text+0x7b): Undefined reference to `bit_stream_close'
collect2: error: ld returned 1 exit status

我究竟做错了什么? 在此先感谢您的帮助!

smuecke

编译bitstream.c以创建bitstream.o

gcc -Wall -c bitstream.c

编译main.c和bitstream.o来创建main(如果在winX上则为main.exe)

gcc -Wall -o main main.c bitstream.o

你不需要每次“编译” stdio.h的原因是它的实现(以及更多)已经编译并在GLibC上运行 也就是说, glibc是一个库(动态库),GCC会在每次编译时将程序链接到它。 您可以通过运行来检查:

ldd hello

假设hello是一个简单的Hello World! 例如,使用printf程序。 你会得到类似的东西:

linux-vdso.so.1 =>  (0x00007fff5f98d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7e985b2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7e98977000)

请参阅第2行: libc.so.6 ,这是您的GNU C库,这就是您每次使用它时都不“编译” stdio.h的原因。


一般情况

你想要做的是实现自己的库。 所以,为了做到这一点,你可以做几件事。

  1. 您在/usr/include下创建一个名为MyLib的目录,并将所有标题放在那里。 这样,您可以使用#include <MyLib/myHeader.h>包含文件。
  2. 方法1:将实现myImp.c编译为目标文件并将该对象放在文件夹/my/libs/path/myImp.o ,每次要使用时,都要编译:

    gcc -o prog prog.c /my/libs/path/myImp.o

    注意:prog.c必须#include <MyLibs/myHeader.h>

  3. 方法2:您可以使用实用程序ar进行存档,并在其中包含所有库。 在这里查看它的手册 每次要使用库中的某些内容时,都要将其与.a库链接。

  4. 方法3:您可以创建一个动态库,这将减少二进制文件的大小(链接.o和ar库是静态链接,这意味着更大的二进制大小)。 你可以使用-fPIC (位置无关代码) gcc标志和其他一些小东西来做到这一点。 我将链接一些资源。


你的具体情况

  1. 编译bitstream.cgcc -c bitstream.c
  2. 将该文件放在/home/you/myLibs/bitstream.o
  3. bitstream.h复制到/usr/include/MyLib/bitstream.h (你需要root
  4. 包括#include <MyLib/bitstream.h>
  5. 使用以下命令编译程序: gcc -o main main.c ~/myLibs/bitstream.o

虽然这远远不够好,但这可以做你想要的。 我建议您阅读如何组织自己的库等等,查看Rusty RusselCCAN库 ,这是如何构建C库的非常好的起点。

真的建议退房CCAN!


资源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM