【问题标题】:gcc shared library with header in the same librarygcc 共享库与同一库中的标头
【发布时间】:2014-12-17 09:25:09
【问题描述】:

我正在尝试使用以下代码编译共享库 (.so): libreceive.h:

#include <stddef.h>
int receive(int sockfd, void *buf, size_t len, int flags);

libreceive.c

#include <stddef.h>
#include <libreceive/libreceive.h>

int receive(int sockfd, void *buf, size_t len, int flags){
    return recv(sockfd, buf, len, flags);
}

这里的问题是我试图将 .h 包含在我正在构建的库中,并同时从 .c 中的同一个库中使用它。 我知道我正在尝试做的事情是可能的,但我无法做到。 请问我该怎么做。

我正在尝试的代码是:

gcc -o libreceive.o -c -include libreceive.h libreceive.c

我收到以下错误:

fatal error: libreceive/libreceive.h: No such file or directory
compilation terminated.

这里的问题是我试图将 .h 包含在我正在构建的库中,并同时从 .c 中的同一个库中使用它。 我知道我正在尝试做的事情是可能的,但我无法做到。 请问我该怎么做。

【问题讨论】:

  • 您尝试过gcc -o libreceive.o -c libreceive.c -I /Path/to/include 吗?考虑到您的libreceive.h 在目录include 中。
  • libreceive 是我要编译的库
  • 在这种情况下,你必须在 gcc 中使用-shared-fPIC 选项,没有提及吗?
  • 我也试过这个:gcc -shared -o libreceive.so -fPIC libreceive.c 在很多变种中,没有运气......
  • @user1928596 如果libreceive.clibreceive.h 在同一文件夹中,则可以在libreceive.c 中使用#include "libreceive.h"。在任何其他想要使用 libreceive 的项目中,您可以使用 #include &lt;libreceive/libreceive.h&gt; 和编译器标志 -I/path/to ,其中 /path/to 包含一个 libreceive 文件夹,(意味着 libreceive.h 的完整路径是 /path/to/libreceive/libreceive.h)跨度>

标签: c gcc shared-libraries


【解决方案1】:

由于libreceive.hlibreceive.c 似乎在同一个目录中(从你的编译器调用来看),正常的方式是

#include "libreceive.h"

为了使用

#include <libreceive/libreceive.h>

libreceive.h 必须位于名为libreceive 的目录中,并且该目录必须是包含路径的一部分。有可能实现这一点,但我认为在这里既没有必要也没有用。

【讨论】:

  • 我在其他地方使用它,在导入时,对于你答案的第二部分,.h 不应该在路径上的另一个文件夹中,我不应该放在前面同一个图书馆
  • @user1928596 是否在其他地方使用它与您在 libreceive.c 中的使用方式无关。
  • 在另一个项目中使用该库时,您不必使用相同的#include 指令。您可以在库本身中使用#include "libreceive.h",其中标头位于同一目录中,并在客户端代码中使用#include &lt;libreceive/libreceive.h&gt;,在其包含路径中从某个目录libreceive 中拉入标头。
  • 我在之前回复的评论中做到了这一点
【解决方案2】:

您在这里遗漏了几个步骤。
考虑以下设置。

文件:add.c

#include "header.h"
int add(int a, int b)
{
    printf("SIZE: %d\n", SIZE);
    return a+b;
}

文件:sub.c

#include "header.h"
int sub(int a, int b)
{
    printf("SIZE: %d\n", SIZE);
    return a-b;
}

文件:header.h,位于名为 include 的目录中。

#include <stdio.h>
#define SIZE 100
int add(int a, int b);
int sub(int a, int b);

所以要逐步建立一个.so 文件。

/* Build `.o` files first */
$ gcc -fPIC -c sub.c -I path/to/include/
$ gcc -fPIC -c add.c -I path/to/include/

/* Build shared library called libsample.so */
$ gcc -shared -o libsample.so add.o sub.o

上述命令将通过名称libsample.so 构建一个.so
.c(如函数)和.h(如#defines)的所有定义都将包含在您的库中。


如何在您的代码中使用它:

考虑文件 档案:main.c

#include <stdio.h>
int main()
{
    int a = 3, b = 4;
    printf("Return : %d\n", add(a, b));
    return 0;
}

利用您的图书馆libsample.so

$ export LD_LIBRARY_PATH=/path/to/direc/containing/.so/file
$ gcc -o exe main.c -lsample -L/path/to/direc/containing/.so/file

上面的命令应该创建一个名为exe的二进制文件。

$./exe
SIZE : 100              /* SIZE Defined in .h file */
Return : 7              /* Defined in add.c */

您可以参考本指南:http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

【讨论】:

  • 我试过你的代码,但是当我这样做并且它确实编译时,当我在另一个类 gcc -o test test.c -lreceive 中使用这个库时它不起作用(我把路径中的库)
  • 谢谢,我在其他地方发现了问题,这两种技术现在都可以工作,所以我会投票并写下我遇到问题的答案,非常感谢
【解决方案3】:

最后我决定按照大家的建议使用#include "libreceive.h"。我遇到的问题是编译器在 /usr/lib 中寻找我的所以当 id do sudo gcc 并且我的 usr 在 /usr/local/lib 有 $LD_LIBRARY_PATH 并且因此 gcc 找不到我的库时,这是默认设置在编译时 另一个问题是调用 thos .so 的程序正在寻找某个不存在的文件夹中的 .h ,我不得不添加它。 谢谢大家的回答

【讨论】:

    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    • 2013-10-25
    • 2013-06-26
    • 2010-10-18
    • 2016-02-17
    相关资源
    最近更新 更多