如何使用图书馆

sin*_*inθ 63 c++ windows macos

出于某种原因,我永远无法使用任何语言的外部库.我正在寻找有关如何使用外部库的说明/解释,以及它们如何工作.当我在线搜索时,我得到的片段似乎永远不适用于我下载并尝试使用的任何库.我在mac和pc上工作,C++示例很好.我使用带有C++插件的eclipse IDE.如果有适用于所有库的指令那将是很棒的.

Vin*_*Pii 153

假设你有一个Unuseful如下定义的类:

档案Unuseful.h:

class Unuseful {
public:
    void printUnusefulStatement();
};
Run Code Online (Sandbox Code Playgroud)

档案Unuseful.cpp:

#include "unuseful.h"
#include <iostream>

void Unuseful::printUnusefulStatement()
{
    std::cout << "Hello world!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

现在,您有另一个需要打印无用语句的类:

Unuseful u;
u.printUnusefulStatement();
Run Code Online (Sandbox Code Playgroud)

这意味着您要使用包含printUnusefulStatement要包含在代码中的特定实现()的外部库.

您可以通过两种方式使用此库:

  1. 通过向编译器提供源代码
  2. 通过提供二进制文件(以前为您的体系结构编译)到链接器

案例1:在编译时使用库

这是最简单的情况.您有必须使用的库的源代码,您只需将其与现有代码(例如main.cpp文件)一起编译.通常,您是库的作者和用户(完成您需要的任务的类).

使用此命令进行编译:

g++ main.cpp unuseful.cpp
Run Code Online (Sandbox Code Playgroud)

允许您在main.cpp文件中使用所需的实现.

案例2:链接库

案例1更常见的是,您没有要使用的库的源代码.您只有头文件(Unuseful.h继续示例)和静态共享库(可能分别是[*] libunuseful.alibunuseful.so文件).

静态库是目标文件(*.o)的存档,它们链接在最终可执行文件中,而共享库则是在运行时动态加载(请查看此页面以便更好地理解差异).

只需*.o使用ar程序归档文件即可创建静态库:

# Create the object files (only one here)
g++ -c unuseful.cpp
# Create the archive (insert the lib prefix)
ar rcs libunuseful.a unuseful.o
Run Code Online (Sandbox Code Playgroud)

使用以下g++ -shared选项创建共享库:

# Create the object file with Position Independent Code[**]
g++ -fPIC -c unuseful.cpp
# Crate the shared library (insert the lib prefix)
g++ -shared -o libunuseful.so unuseful.o
Run Code Online (Sandbox Code Playgroud)

我们假设您现在拥有Unuseful.h文件和共享库(libunuseful.so文件),并且您有一个main.cpp实例化Unuseful对象并调用该printUnusefulStatement方法的文件.

如果您尝试编译此文件(g++ main.cpp),链接器将会抱怨,因为它无法找到该printUnusefulStatement符号.

是时候使用这个库了:

g++ main.cpp -L. -lunuseful
Run Code Online (Sandbox Code Playgroud)

-L选项告诉链接器在哪里搜索库文件,该-l标志告诉链接器要使用的库的名称(没有lib前缀).

现在创建了可执行文件(a.out因为我没有指定其他名称),并且您已经使用库来实现所需的功能(printUnusefulStatement).

由于共享库是在运行时加载的,因此a.out可执行文件的执行可能会失败,因为系统无法找到库.通常,这可以通过适当设置环境变量来解决,该环境变量指示用于搜索动态库的路径:

# Set the LD_LIBRARY_PATH [*]
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
Run Code Online (Sandbox Code Playgroud)

完成后,现在您的可执行文件已经编译完毕,它将能够运行并加载所需的库.

结论

这是对图书馆的快速概述,我希望可以帮助您了解它们如何被使用并提供给其他人.

如果您感兴趣,有许多方面需要更详细地研究:g++创建共享库时的ar选项,选项,环境变量,共享库格式等等.

[*]:在Unix环境中

[**]:如果目标机器支持,则发出与位置无关的代码,适用于动态链接并避免对全局偏移表大小的任何限制.此选项对m68k,PowerPC和SPARC产生影响.与位置无关的代码需要特殊支持,因此仅适用于某些机器.[来自g ++手册页]

  • 刚发现这个...非常感谢这个明确的解释.我有整个过程,但小细节搞砸了我 (3认同)
  • 很酷的解释。只是对这个命令“g++ main.cpp -L”感到好奇。-lunuseful`,为什么`-L`后面没有空格以及为什么`-lunuseful`而不是使用全名`-llibunuseful`。是否有任何遗留原因,因为这让初学者感到困惑。 (3认同)

Vik*_*pov 6

这是你开始的地方 http://en.wikipedia.org/wiki/Library_(computing)

基本上,"库"是已编译函数和类声明的集合.

在Mac上还有"框架",它有点类似于Pascal的单元,包含声明和编译的代码.

在Java或C#等托管语言中,有包和程序集.两者都与图书馆密切相关.

要在C或C++中使用库,您必须拥有.lib文件(或大多数基于POSIX或GCC工具链的编译器的.a文件)以及编译到.lib文件中的函数原型.根据您的开发环境(对于Eclipse,您最有可能使用GCC编译器和带有LD链接器的GNU工具链),您只需指定库文件(.lib或.a)作为链接器的输入.大多数情况下,库都附带包含函数原型定义的头文件.

即使您不知道链接器,这很奇怪,库仍然隐式使用在您的程序中 - std :: cout位于libstdc ++或C运行时库中.

作为一个庞大的库和一组有用的C++类的例子,你可能想看看Boost.

要在Windows上编写GUI,您可以使用MSDN中描述的WinAPI.

要在Mac上编写GUI,您可以使用与WinAPI有些类似的Carbon API,但现在已弃用.为MacOS编写"合法"GUI的唯一方法是使用Cocoa和Objective-C.

要编写跨平台GUI,您可以使用大量库:Qt,wxWidgets,GTK.

最后的但并非最不重要的.C++不是GUI的最佳语言.

  • 最后一点有点值得商榷,最好!=最简单,很多严肃的用户界面仍然用C++编写.例如,所有浏览器都包括Chrome,它是新的,并且在设计时具有丰富的替代品. (9认同)
  • 好.我同意.这完全取决于.当考虑到可移植性时,不需要考虑C/C++.但是,前端可以以特定于平台的方式实现,并且C++可以用于所有业务逻辑. (2认同)