静态库设置强制导出后,动态库一定包含此符号吗

在开发中,这是一个经典且容易踩坑的链接行为。简单结论是:默认情况下,打出来的 .so 不会包含该函数。

1. 为什么“强制导出”无效?

静态库(.a.lib)本质上是一堆对象文件(.o.obj)的“压缩包”。链接器在构建动态库(.so)时,遵循以下逻辑:

  • 按需提取: 链接器只有在发现动态库的代码中存在一个“未定义引用(Undefined Reference)”时,才会去静态库里寻找对应的符号,并将包含该符号的整个 .o 文件拉进结果中。
  • 无视属性: 虽然你在代码里写了 __attribute__((visibility("default")))(Linux)或 __declspec(dllexport)(Windows),但这只是该符号在 .o 文件里的一个“标记”。
  • 结果: 如果你的动态库没有代码调用这个函数,链接器根本就不会去加载那个 .o 文件。既然文件没被加载,里面的“导出标记”自然也就不会生效,最终 .so 的导出表里就不会有它。

阅读全文

子Shell以及返回值运行机制

这是一个非常经典且重要的 Shell 执行机制问题。直接给结论:

  1. 会新建子进程(子 Shell)吗?
    会。 使用 bash $PushAssets 会启动一个新的 Bash 进程来运行该脚本。
  2. set -e 能触发退出吗?
    能。 如果子脚本返回非 0 值,父脚本在 set -e 模式下会立即终止。

阅读全文

c++ 析构函数的三种变体

在 C++ 的 Itanium ABI(应用二进制接口,被 GCC 和 Clang 等主流编译器广泛采用)中,为了处理复杂的继承(尤其是虚继承)和不同的对象生命周期管理需求,编译器会为同一个类生成三种主要的析构函数变体:D0D1D2

阅读全文

Android ShareContext Demo

了解了,你的需求是:只有一个 GLSurfaceView(拥有一个渲染线程),但你需要开启另一个后台线程(子线程)并在该线程中操作 OpenGL 资源(如异步加载纹理),这两个线程需要共享同一个 Context。

阅读全文

c++函数返回值存在了哪里

这是一个非常深入且经典的问题。你的直觉很准:如果变量在函数内部的栈帧里,函数返回后栈帧销毁,引用必然指向一片非法内存。

但这里的关键在于:返回的对象并不在“已经销毁”的那个函数栈帧里。

阅读全文

std::vector<T> clear详解

这是一个非常核心的问题。在 C++ 标准库中,std::vector::clear() 的行为是非常明确的。为了让你彻底理解,我们从逻辑行为源码实现(以 GCC 的 libstdc++ 为例)以及内存状态三个维度来剖析。

阅读全文