- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
假设,我有一个 C 结构,DynApiArg_t
。
typedef struct DynApiArg_s {
uint32_t m1;
...
uint32_t mx;
} DynApiArg_t;
这个结构的指针作为参数传递给函数 say
void DynLibApi(DynApiArg_t *arg)
{
arg->m1 = 0;
another_fn_in_the_lib(arg->mold); /* May crash here. (1) */
}
存在于动态库 libdyn.so
中。此 API 通过 dlopen/dlsym
调用过程从可执行文件调用。
如果此动态库更新到版本 2,其中 DynApiArg_t
现在有新成员,比如 m2
,如下所示:
typedef struct DynApiArg_s {
uint32_t m1;
OldMbr_t *mold;
...
uint32_t mx;
uint32_t m2;
NewMbr *mnew;
} DynApiArg_t;
如果没有完全重建通过 dlopen/dlsym
调用此 API 的可执行文件或其他库,每次调用此 API 时,我都会看到进程崩溃,这是由于任何成员的某些取消引用在结构中。我知道访问 m2 可能是个问题。但是可以看到像下面这样访问成员 mold
会导致崩溃。
typedef void (*fnPtr_t)(DynApiArg_t*);
void DynApiCaller(DynApiArg_t *arg)
{
void *libhdl = dlopen("libdyn.so", RTLD_LAZY | RTLD_GLOBAL);
fnPtr_t fptr = dlsym(libhdl, "DynLibApi");
fnptr(arg); /* actual call to the dynamically loaded API (2) */
}
在通过 fnptr 调用 API 时,在标记为 (2) 的行中,当在 (1) 处访问旧的/现有成员(在 lib 的 v1 中,最初编译 DynApiCaller 时)时,它恰好是任何垃圾有时甚至是 NULL
。
每次更新依赖库时,如果不完全重新编译可执行文件,处理此类更新的正确方法是什么?
我见过用符号符号命名的库,版本号如 libsolid.so.4
。有什么与此版本控制系统相关的东西可以帮助我吗?如果有的话,您能指出这些文件的正确文档吗?
最佳答案
有很多方法可以解决这个问题:
在动态库名称中包含 API 版本。
您使用 dlopen("libfoo.so.4")
而不是 dlopen("libfoo.so")
。库的不同主要版本本质上是独立的,可以在同一系统中共存;因此,该库的包名称将是例如libfoo-4
。您可以同时安装 libfoo.so.4
和 libfoo.so.5
。次要版本,例如 libfoo-4.2
,安装 libfoo.so.4.2
,并将 libfoo.so.4
符号链接(symbolic link)到 libfoo.so .4.2
.
最初用零填充定义结构(在早期版本的库中要求为零),并让更高版本重用填充字段,但保持结构大小相同。
<使用版本符号名称。这是一个 Linux 扩展,使用 dlvsym()
.单个共享库二进制文件可以实现同一动态符号的多个版本。
使用 resolver functions在加载时确定符号。这允许例如要在运行时选择的硬件架构优化函数变体,但对于基于 dlopen()
的方法而言用处不大。
使用结构来描述库 API,并使用版本化函数来获取/初始化该 API。
例如,您的库的版本 4 可以实现
struct libfoo_api {
int (*func1)(int arg1, int arg2);
double *data;
void (*func2)(void);
/* ... */
};
并且只导出一个符号,
int libfoo_init(struct libfoo_api *const api, const int version);
调用该函数将使用支持的符号初始化 api
结构,假设该结构对应于指定版本。一个共享库可以支持多个版本。如果不支持某个版本,它会返回失败。
这对于插件类型的接口(interface)特别有用(尽管 _init
函数更可能调用应用程序提供的功能注册函数,而不是填充结构),因为单个文件可以包含针对多个版本的优化功能,针对多个兼容的硬件架构(例如,具有不同 SSE/AVX/AVX2/AVX512 支持的 AMD/Intel 架构)进行了优化。
请注意,上述实现细节可以“隐藏”在头文件中,从而使使用共享库的实际 C 代码更加简单。它还有助于使相同的 API 在多个操作系统上工作,只需更改头文件以使用在该操作系统上最有效的方法,同时保持实际的 C 接口(interface)相同。
关于c - 在参数 typedef 更改时重建动态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45467653/
如果我使用 alter index x rebuild 重建不可用的索引,是否会重新评估之前使用该索引的任何 SQL 的执行计划? 我知道在我使用的数据库版本 - Oracle 10.2.0.4.0
我正在研究 3d 重建。现在当我考虑一对图像时。我有一组对应点。我有我的相机详细信息。例如我有焦点细节,旋转和平移矩阵(4 * 4)。我想在 3D(三角剖分)中投影我的点。因此,据我所知,因子代数非常
从教程中:https://programtalk.com/vs2/?source=python/8176/opencv-python-blueprints/chapter4/scene3D.py 我不
我需要您的帮助和建议。这个问题包括以下几项:某房间的照片,该房间站在严格固定位置的房间内(一个房间围绕轴线旋转)。如何将所有这些图片组合在一起,从而产生一种效果,就像我们用眼睛看到的一样?从一点开始就
嘿那里,以下问题:我在工作中使用一个相当奇怪的 Linux 发行版(Centos 5),它似乎有一个较旧的内核(或者至少在内核中存在一些差异),并且您不能简单地更新它。我需要安装的程序需要一个函数 c
我读了一些关于受限玻尔兹曼机的文章。这些机器的重建能力经过了测试。我了解训练是如何进行的,但不了解重建是如何完成的。有人可以给我一些提示吗? 最佳答案 杰夫·辛顿 (Geoff Hinton) 的演讲
如果轻量级迁移失败,我将尝试重建核心数据数据堆栈,并将用户送回登录屏幕。我正在通过将一对多关系更改为一对一关系来对此进行测试。 起初,我在删除新的 persistentStoreCoordinator
以下所列示例中中 `table_name` 表示数据表名,`index_name` 表示索引名,column list 表示字段列表(如:`id`,`order_id`)。 1、创建索引 索引的
当您根据 ListView.builder 和 ListView.separated valueKey = key; return _messages
切换底部导航页面后,我有一个非常烦人的谷歌地图 flutter 重建问题。我已经坚持了最后一次缩放和相机位置,但是每次我进入 map 页面时,小部件都会自行重建。如何预防? 最佳答案 采用 Autom
我是 Python 的新手。我在重建一个错误的 Dataframe 时遇到了麻烦。我的数据框如下所示: df = pd.DataFrame({'col1': ['id 1', 'id 2', 'tes
我正在尝试从 2 个图像中实现 3d 重建。我遵循的步骤是, 1. Found corresponding points between 2 images using SURF. 2. Impleme
// Start with this JSON var initialJson = { "rows": [{ "ID": 123, "Data": 430910, "Ver
在有状态的小部件中,我有一个导航部分,用户可以在其中选择父项,并在子项下方显示。 当我选择父级也可以重建子部件时,但是当我导航抛出父项而不选择一个子部件时,父级也可以重建(这是正常的),但是子部件也可
我有一个网络摄像头,它可以围绕人的头部以给定的角度步长旋转,并为每一步获取一张图片。 我正在寻找一个免费的开源库,该库从获取的图像集开始,使我能够生成代表人头部的 3D 表面,或者至少是定义明确的 3
我想从一行中读取一个字符串,然后将其放入一个变量中,该变量随后用作文件名。该字符串位于 .csv 文件中的第二行末尾。由于不必要的标题,需要删除第一行。还有‘;’旧 .csv 文件中使用的内容需要替换
我正在使用file-embed如此封装: import qualified Data.ByteString as B import qualified Data.ByteString.Internal
我的 makefile 总是重建,不明白为什么.. 这里是: SRC = $(DIR)/my_getnbr.c \ $(DIR)/my_isneg.c \ $(DI
我有一个附带编辑器的 Eclipse 插件。 我添加了更改语法突出显示颜色的首选项,但这些更改仅在我手动重新启动编辑器后才适用。 我通过一个 DefaultDamagerRepairer 实现了语法高
我有一段 php 可以输出 div(取决于数组中有多少个)并为该 div 分配一个 id(即 div_1、div_2)等 我还设置了一个隐藏字段,其中包含输出了多少个 div 的计数(divcount
我是一名优秀的程序员,十分优秀!