如何使用库
How to use Libraries
由于某种原因,我永远无法使用任何语言的外部库。我正在寻找有关如何使用外部库以及它们如何工作的说明/解释。当我在网上搜索时,我得到的片段似乎永远不会适用于我下载和尝试使用的任何库。我在Mac和PC上工作,C++示例都很好。我将 eclipse IDE 与 C++ 插件一起使用。如果有适用于所有库的说明,那就太好了。
假设您有一个类Unuseful
定义如下:
文件Unuseful.h
:
class Unuseful {
public:
void printUnusefulStatement();
};
文件Unuseful.cpp
:
#include "unuseful.h"
#include <iostream>
void Unuseful::printUnusefulStatement()
{
std::cout << "Hello world!" << std::endl;
}
现在,您有另一个需要打印无用语句的类:
Unuseful u;
u.printUnusefulStatement();
这意味着您希望使用包含要包含在代码中的特定实现(printUnusefulStatement
(的外部库。
您可以通过两种方式使用此库:
- 通过向编译器提供源代码
- 通过向链接器提供二进制文件(以前已针对体系结构编译(
情况 1:在编译时使用库
这是最简单的情况。您拥有必须使用的库的源代码,只需将其与现有代码(例如main.cpp
文件(一起编译即可。通常,您是库(完成所需任务的类(的作者和用户。
使用此命令编译:
g++ main.cpp unuseful.cpp
允许您在main.cpp
文件中使用所需的实现。
案例 2:链接库
与案例 1 相比,您没有要使用的库的源代码。您只有头文件(Unuseful.h
,继续示例(和静态或共享库(可能[*]分别libunuseful.a
和libunuseful.so
文件(。
静态库是链接在最终可执行文件中的对象文件(*.o
(的存档,共享库是在运行时动态加载的(查看此页面以更好地了解差异(。
静态库是通过简单地使用 ar
程序存档*.o
文件来创建的:
# Create the object files (only one here)
g++ -c unuseful.cpp
# Create the archive (insert the lib prefix)
ar rcs libunuseful.a unuseful.o
共享库是使用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
假设现在您有 Unuseful.h
文件和共享库(libunuseful.so
文件(,并且您有一个实例化 Unuseful
对象并调用 printUnusefulStatement
方法的main.cpp
文件。
如果尝试编译此文件 ( g++ main.cpp
(,链接器将抱怨,因为它找不到printUnusefulStatement
符号。
是时候使用库了:
g++ main.cpp -L. -lunuseful
-L
选项告诉链接器在何处搜索库文件,-l
标志告诉链接器要使用的库的名称(不带 lib
前缀(。
现在创建了可执行文件(a.out
,因为我没有指定不同的名称(,并且您已经使用库来实现所需的功能(printUnusefulStatement
(。
由于共享库是在运行时加载的,因此a.out
可执行文件的执行可能会失败,因为系统无法找到该库。通常,可以通过适当设置环境变量来解决,该变量指示使用哪些路径来搜索动态库:
# Set the LD_LIBRARY_PATH [*]
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
完成后,现在您的可执行文件已编译,它将能够运行和加载所需的库。
结论
这是对库的快速概述,希望能帮助您了解如何使用它们并提供给其他人。
如果您有兴趣,有许多方面需要更详细地研究:创建共享库时的g++
选项、ar
选项、环境变量、共享库格式等。
[*]:在 Unix 环境中
[**]:如果目标机器支持,则发出与位置无关的代码,适用于动态链接,避免对全局偏移表的大小有任何限制。此选项在m68k,PowerPC和SPARC上有所不同。与位置无关的代码需要特殊支持,因此仅适用于某些计算机。[来自 g++ 手册页]
这是你开始的地方http://en.wikipedia.org/wiki/Library_(计算(
基本上,"库"是已编译函数和类声明的集合。
在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,您可以使用Carbon API,它有点类似于WinAPI,但现在已被弃用。为MacOS编写"合法"GUI的唯一方法是使用Cocoa和Objective-C。
要编写跨平台GUI,您可以使用很多库:Qt,wxWidgets,GTK等。
最后,但并非最不重要的。C++不是GUI的最佳语言。
使用外部C++库的最佳方法是使用C++包管理器,去学习其中之一:
- 柯南
- vcpkg
- 猎人
- CPPAN
- 构建2
其中一些涉及使用 CMake,您可以在此处找到编写良好的教程。
.
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- C++:TypeDef使用元组
- 使用std::multimap迭代器创建std::list
- 从不同线程使用int64的不同字节安全吗
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么在全局范围内使用"extern int a"似乎不行?
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用Google Mock来模拟gettimeofday()
- 如何使用默认参数等选择模板专业化
- 为什么使用 "this" 指针调用派生成员函数?
- 使用新行和不使用新行读取文件
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 如何确定我已使用非编码文件到达 EOF?
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 使用CMake创建QML插件
- 使用 LLVM 的 libc++ 时,__1 符号从何而来?
- 在std::cout之后使用std::cin时,换行符从何而来
- 为什么以及在何处在C++中使用引用和指针
- 基例如何影响使用递归函数的哪些行