我想编写一个快速访问的C库,只包含头文件而不使用编译库。为此,我已将我的代码直接包含在我的头文件中。
头文件包含:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef INC_TEST_H_
#define INC_TEST_H_
void test(){
printf("hello\n");
}
#endif
我的程序无法编译,因为我有多个函数test()
的引用。如果我有一个正确的源文件与我的标题,它可以正常工作。
是否可以通过在C app中包含代码来仅使用头文件?
答案 0 :(得分:6)
在标题中包含代码通常是一个非常糟糕的主意。
如果您有“file1.c”和“file2.c”,并且在每个中都包含您的“编码.h”,那么在编译的链接部分,将有2个具有全局范围的测试功能(一个在file1.c中,另一个在file2.c中)。
你可以使用“静态”这个词,以便说明该函数仅限于包含“编码.h”的.c中,但是再次,这是一个坏主意。
至少但不是最后一个:你打算如何创建一个没有.so / .a文件的库?这不是库,这是您项目中直接复制/过去的代码。
当你的“库”中出现错误时,除了纠正你的代码,在每个项目中重新发布它并重新编译每个项目,你都将无法解决问题,忽略了动态库的重点:能够“只是“更正库而不触及使用它的每个程序。
答案 1 :(得分:3)
如果我理解你正确的要求,你想创建一个&#34;库&#34;这是严格的源代码,必要时获得#incude
d,而不是单独编译和链接。
正如您所发现的,当您处理函数时,这并不容易 - 编译器会抱怨多个定义(对象定义会遇到同样的问题)。
此时你有几个选择。
您可以声明函数static
:
static void test( void )
{
...
}
static
关键字限制了该功能对当前翻译单元的可见性,因此您不会在链接时遇到多个定义错误。这意味着每个翻译单元都在创建自己独立的&#34;实例&#34;该函数,导致一些代码膨胀和稍长的构建时间。如果你能忍受,那么这是最简单的解决方案。
您可以使用宏代替函数:
#define TEST() (printf( "hello\n" ))
除了宏不是函数并且不像函数那样。而基于宏观的&#34;图书馆&#34;确实存在,它们并不是无法正确实现的,需要相当多的思考。请记住,宏参数不会被评估,它们只是在适当的位置进行扩展,如果传递带副作用的表达式,可能会导致问题。典型的例子是:
#define SQUARE(x) ((x)*(x))
...
y = SQUARE(z++);
SQUARE(z++)
扩展为((z++)*(z++))
,这会导致未定义的行为。
单独编译是一件好事,你不应该试图避免它。在一个源文件中执行所有是不可扩展的,并且会导致维护问题。
答案 2 :(得分:2)
我的程序没有编译,因为我有多个对test()函数的引用
这是因为包含该函数的.h文件并在多个C源文件中编译。因此,链接器会多次遇到具有全局作用域的函数。
您可以将函数定义为static void test()
{
printf("hello\n");
}
,这意味着它只有curent编译单元的范围,所以:
{{1}}