C++: 如何把源码编译成SDK提供第三方使用

在我们开发过程中,经常会遇到提供SDK的情况,对于C++语言,是可以方便地将源码封装成静态库或者动态库然后打包提供给第三方使用的。这样,一方面可以保护源码,另一方面也简化了对方的使用过程。

目录

一、关于动态库和静态库

 二、代码示例

1、SDK封装

2、SDK使用


一、关于动态库和静态库

C++中的动态库(Dynamic Link Library,DLL)和静态库(Static Library,LIB)是两种不同的库类型,它们在编译、链接和运行时的行为有所不同。另外,它们在不同平台上后缀也不同,linux上分别是.so/.a,windows上分别是.dll/.lib。

以下是它们的主要区别:

  1. 编译方式

    • 静态库:在编译时将库文件(.a或.lib)与应用程序一起编译链接,生成一个单一的可执行文件。静态库中包含的是编译后的机器代码。
    • 动态库:在编译时不与应用程序一起编译链接,而是在程序运行时动态加载。动态库中包含的是编译后的代码,但不是直接嵌入到可执行文件中。
  2. 链接方式

    • 静态库:在链接阶段,静态库的内容被复制到最终的可执行文件中,因此生成的可执行文件体积较大。
    • 动态库:在链接阶段,只将动态库的引用信息添加到可执行文件中,实际的代码在运行时才被加载。
  3. 内存使用

    • 静态库:由于代码被复制到每个使用它的可执行文件中,因此每个程序实例都包含库代码的副本,可能会占用更多的内存。
    • 动态库:多个程序可以共享同一份动态库代码,因此内存使用更高效。
  4. 更新和维护

    • 静态库:如果库代码更新了,需要重新编译所有使用该库的应用程序,因为它们包含了库的代码副本。
    • 动态库:只需更新动态库文件,所有使用它的应用程序在下次运行时都会加载新的库代码,便于维护和升级。
  5. 分发和部署

    • 静态库:分发应用程序时,不需要额外的库文件,因为所有需要的代码都已经包含在可执行文件中。
    • 动态库:分发应用程序时,除了可执行文件,还需要确保相应的动态库文件在目标系统上可用。
  6. 兼容性和依赖性

    • 静态库:由于代码是静态编译的,因此不容易出现版本冲突或兼容性问题。
    • 动态库:如果多个应用程序依赖不同版本的动态库,可能会出现兼容性问题,需要更仔细地管理库的版本。
  7. 性能

    • 静态库:由于代码是直接包含在可执行文件中的,因此访问速度可能更快,没有运行时加载的开销。
    • 动态库:在程序启动时需要加载,可能会有轻微的性能开销,但运行时共享内存可以减少总体内存占用。
  8. 安全性

    • 静态库:由于代码是静态编译的,可能更难被恶意修改。
    • 动态库:如果动态库文件被恶意修改,可能会影响所有使用它的应用程序。

 二、代码示例

1、SDK封装

首先建立一个文件夹:MyMathLibrary,用于存放我们所有的SDK相关内容。然后,在里面编写头文件和源文件。整体目录结构如下:

├── CMakeLists.txt
├── include
│   └── MyMath.h
└── src
    └── Add.cpp

其中头文件“MyMath.h”定义如下:

#ifndef MYMATH_MYMATH_H
#define MYMATH_MYMATH_H

namespace mymath {
    int Add(int a, int b);
}

#endif // MYMATH_MYMATH_H

源文件"Add.cpp"定义如下:

#include "MyMath.h"

namespace mymath {
    int Add(int a, int b) {
        return a + b;
    }
}

“CMakeLists.txt”内容如下(注意:这里会把编译好的库文件和头文件安装到/usr/local,也可以注释掉这部分,直接从build里面取库文件):

cmake_minimum_required(VERSION 3.10)
project(MyMathLibrary)

# 设置C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 包含头文件目录
include_directories(include)

# 添加静态库目标
add_library(MyMath STATIC src/Add.cpp)

# 安装库和头文件
install(TARGETS MyMath ARCHIVE DESTINATION lib)
install(FILES include/MyMath.h DESTINATION include)

然后,我们新建一个build文件夹,并执行以下命令:

cd build
cmake ..
make

这样就会在build文件夹下得到“libMyMath.a”,这就是编译好的静态库。如果想用动态库,则需要将“CMakeLists.txt”中“add_library(MyMath STATIC src/Add.cpp)”这一句改为:

add_library(MyMath SHARED src/Add.cpp)

这样的话,就会在build里面得到“libMyMath.so”这个动态库。

2、SDK使用

编译好动态库或者静态库之后,我们将库文件和头文件打包一下,就是所谓的SDK了,这里面的内容就是交给第三方使用的最小合集。也即,如果别人想要使用我们的库中定义的方法,需要拿到这个库文件,并需要从头文件知道相关方法的声明。

现在我们假设上面代码的编译过程是包含install的,那么相关库都已经放在了/usr/local了,头文件在/usr/local/include,库文件在/usr/local/lib。

现在我们新建一个文件夹,就叫做MyMathExample,然后在里面新建如下目录结构:

├── CMakeLists.txt
└── src
    └── main.cpp

其中main.cpp是我们的调用库的代码:

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

int main() {
    int result = mymath::Add(3, 4);
    std::cout << "The sum is: " << result << std::endl;
    return 0;
}

CMakeLists.txt里面是编译相关的内容:

cmake_minimum_required(VERSION 3.10)
project(MyMathExample)

# 设置C++标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 直接指定MyMath库的路径
set(MyMath_LIBRARY "/usr/local/lib/libMyMath.a")
set(MyMath_INCLUDE_DIR "/usr/local/include")

# 包含MyMath的头文件目录
include_directories(${MyMath_INCLUDE_DIR})

# 添加可执行文件
add_executable(MyMathExample src/main.cpp)

# 链接MyMath库
target_link_libraries(MyMathExample "${MyMath_LIBRARY}")

这里,我们定义了库文件和头文件的路径,然后在编译时指定。

同样的,我们新建一个build文件夹,并执行以下命令:

cd build
cmake ..
make

然后,执行build中的 MyMathExample:

./MyMathExample  # 会得到结果:The sum is: 7

That's all~!

参考:

C++11 - cppreference.com

演练:创建和使用自己的动态链接库 (C++) | Microsoft Learn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AICVHub

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值