English 中文(简体)
include目录与lib目录概念问题
原标题:include directories vs. lib directory concept question
  • 时间:2011-02-16 21:32:11
  •  标签:
  • c++

链接到include文件和链接到lib文件之间有什么区别?

我是C/C++的新手,很难弄清楚使用include文件和静态lib文件调用函数之间的区别。在我看来,include文件具有可以像.lib文件一样调用的函数。

最佳回答

在C++(以及C和其他类似语言)中,一个函数被称为同时具有声明定义

声明只是一个简短的语句,声明函数的存在及其接口的外观。考虑一个将两个整数相加的基本函数add。其声明可能如下所示:

int add(int, int);

这意味着“存在一个函数add,它接受两个整数并返回一个整数”。它没有指定函数的实际作用,尽管我们可以根据它的名称进行很好的猜测。

函数的定义是我们精确定义函数的作用的地方。这可能是您认为实际的函数代码。以add函数为例:

int add (int a, int b)
{
    return a + b;
}

那么,这与你的问题如何契合呢?好吧,假设我们在math.cpp中有许多数学函数:

// math.cpp

int add (int a, int b)
{
    return a + b;
}

int sub(int a, int b)
{
    return a - b;
}

还假设我们决定在main.cpp中的主函数中使用其中一些:

// main.cpp

#include <iostream>

int main (int argc, char* argv[])
{
    std::cout << "1 + 2 = " << add(1, 2) << std::endl;
    std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}

如果您尝试按原样编译main.cpp,它会抱怨不知道addsub是什么。这是因为您试图在不声明它们存在的情况下使用它们——这正是声明的目的。因此,您可以执行以下操作:

// main.cpp

#include <iostream>

int add(int, int);
int sub(int, int);

int main (int argc, char* argv[])
{
    std::cout << "1 + 2 = " << add(1, 2) << std::endl;
    std::cout << "8 - 3 = " << sub(8, 3) << std::endl;
}

这是可行的,但不是很灵活。如果我们添加一个新函数mul,我们需要将其声明添加到main.cpp和使用它的其他所有.cpp文件中(如果您有很多.cppmath.h),这样我们只需要在一个位置维护声明列表。然后,我们只需将math.h包含到任何使用数学函数的文件中。这就是头文件(也称为包含文件)的用途。

这很有效,但可能会更好。实际上,我们有一个main.cpp文件和一个math.cpp文件,这两个文件都是在每次编译程序*时编译的。如果你的数学函数根本没有改变,那么无论何时重新编译main.cpp,最好只编译一次,并将预编译的定义插入到可执行文件中?这正是.lib文件的用途。它们包含相关函数的定义的预编译代码。您仍然需要include文件来让您知道库中存在哪些函数。

编译的链接阶段的目的是获取这些预编译的函数和您刚刚编译的函数,并将它们汇总到一个可执行文件中。

Essentially, you can look at a static lib as the pre-compiled code for a number of predefined functions, and its matching include file as a tool to let any code wanting to use those functions know which are available and what their description is.


* This is not strictly true, but is sufficient for our purposes here.
问题回答

为了提供一个更简单的答案:

.lib文件是预编译的库。如果包含.lib,还需要包含.h/hpp头文件,这样编译器就知道如何访问.lib中的函数。

编译程序时,库中使用的所有函数都只是链接的,不会再次编译。

包含文件通常包含符号(函数、变量)的声明。这使编译器知道名称是在(头中)或其他地方定义的(在声明的情况下):

a.h:

void a_useful_function(); //declaration 

但你也可以有一个定义:

a.h:

void a_useful_function()
{
    //... do something
}

库是函数的累积,这些函数通常由头公开。标头通常是要链接的库的接口。

然而,也存在仅头库,它们的声明和定义代码位于同一文件中。

你在问题中提到了包含目录。include目录是编译器搜索以解析#include“a.h”预处理器指令的位置。

但也有库目录,链接器在其中搜索所需的库,这些库通常为头中的声明提供实现(定义)。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签