【问题标题】:C-source file for /usr/include header (e.g. stdio.h)/usr/include 标头的 C 源文件(例如 stdio.h)
【发布时间】:2016-07-31 10:34:48
【问题描述】:

我想尝试使用 openssl 并因此想要更改源。 我找到了包含#include <openssl/ec.h> 的代码,并且显然使用了该标头中的函数。但是,我找不到文件 ec.c,据我所知,该文件通常位于标题中(/usr/include/openssl/ec.h)。同样在openssl的github源码(https://github.com/openssl/openssl),ec.h位于openssl-master/include/openssl但是没有ec.c

所以:gcc 在哪里寻找 ec.h 中定义的方法?

感谢您的回答!

【问题讨论】:

  • .h.c 通常存储在一起。此外,这些函数很可能不是“定义”的,而是在ec.h 中声明的,所以请清楚这一点。 GCC 可能根本不会自行查找实现文件,而是假设您像使用 pthread (-lpthread) 一样手动指定库。
  • 在 C 中没有要求每个X.h 文件都有一个对应的X.c 文件(尽管经常有)。编译器(实际上是链接器)将在传递给它的库(共享或静态)中查找未解析的符号。
  • @kaylum:不仅是共享库:还有静态库。
  • @MartinBonner 是的,同意,很好的说明。

标签: c++ c gcc header include


【解决方案1】:

对于大型库项目(如 openssl),通常将头文件放在 include 目录中,将源文件放在单独的源目录中。客户端应用程序需要包含文件和编译的库 - 但它们不需要需要库源文件。

回答你的问题:

https://github.com/openssl/openssl/blob/master/apps/ec.c

此外,函数在ec.h定义。它们在此处声明,并在相应的 .c 文件中定义。声明和定义的区别在 C 和 C++ 中都是一个重要的区别。

最后,必须有一个ec.c 文件对应于ec.h 标头。这是一个常见的约定,但其他库的结构可能只有一个标头(以便用户使用),但有许多单独的源文件(帮助组织库)。所以你可能有ec_core.cec_sign.cec_encrypt.cec_key_exchange.c

【讨论】:

  • 谢谢你的帮助,但仍然:gcc如何知道在ec.h中声明的函数foo位于crypto/ec/ec_core.c而不是crypto/ec/ec_sign.c?因为当我包含标题时,我只包含 #include <openssl/ec.h> 并且没有目录可以找到定义...!?!感谢您澄清定义/声明的差异,我会记住的!
  • 当 gcc 编译 ec_core.c 时,它会找到其中定义的所有函数,并使用函数的目标代码创建 ec_core.o。在简单的情况下,链接器将获得所有.o 文件并将它们链接在一起。使用 openssl 之类的工具,库 (?ar?) 实用程序将 .o 文件一起收集到一个库中,并且您的测试程序与该库链接。
【解决方案2】:

我了解到您想修改 OpenSSL 源代码。在 C 编程中,所有 /h 文件都没有必要有一个对应的 .c 文件。

头文件和源文件之间必须存在一对多的映射关系 文件。即使您没有对应的 ec.c 用于 ec.h 文件 在 OpenSSL 下,ec.h 中声明的功能可能会被定义 其他地方(在 openSSL 或其他任何其他源文件中) 依赖)。最后你的 OpenSSL 二进制文件是 libeay.lib/.so 和 SSLeay.lib/.so(考虑到 linux 平台)会有符号 为相应的函数声明定义。

我假设您正在尝试查看系统安装的 OpenSSL 库,在那里您只会找到头文件和二进制文件,而不是源代码。您可以从 git 存储库下载 OpenSSL 源代码并尝试对源代码进行更改并构建它。

如前所述,您可能在某些地方以源格式或二进制格式定义了函数,以便最终输出(二进制文件)与定义相关联。

【讨论】:

  • 嗯,我现在明白了。所以#include 获取头文件中声明的预编译二进制函数。无法回头查看哪些源文件包含特定标头。它只能反过来工作。谢谢
猜你喜欢
  • 2015-01-17
  • 1970-01-01
  • 1970-01-01
  • 2014-11-24
  • 2013-12-05
  • 2012-07-26
  • 1970-01-01
  • 2011-01-30
  • 2021-10-01
相关资源
最近更新 更多