静态库改为动态库后,可以影响到程序的执行结果

简介: 源于systemd的例子 先看bus-error.h中的一个宏: #define BUS_ERROR_MAP_ELF_REGISTER \ __attribu...

源于systemd的例子


先看bus-error.h中的一个宏:

#define BUS_ERROR_MAP_ELF_REGISTER                                      \
        __attribute__ ((__section__("BUS_ERROR_MAP")))                  \
        __attribute__ ((__used__))                                      \
        __attribute__ ((aligned(8)))

意思是将数据定义在BUS_ERROR_MAP段,8字节对齐,标记为已使用的


bus-error.c中定义了一个数组:

BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_standard_errors[] = {
        SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.Failed",                           EACCES),
        SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.NoMemory",                         ENOMEM),
        ......
        SD_BUS_ERROR_MAP("org.freedesktop.DBus.Error.ObjectPathInUse",                  EBUSY),
        SD_BUS_ERROR_MAP_END
};


test-bus-error.c中定义了两个数组:

BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map test_errors[] = {
        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error", 5),
        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-2", 52),
        SD_BUS_ERROR_MAP_END
};

BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map test_errors2[] = {
        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-3", 33),
        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-4", 44),
        SD_BUS_ERROR_MAP("org.freedesktop.custom-dbus-error-33", 333),
        SD_BUS_ERROR_MAP_END
};


如果将bus-error.c编译到静态库,然后test-bus-error.c去连接该静态库,bus-error.c和test-bus-error.c中定义的BUS_ERROR_MAP段中的数据会合并到同一个ELF的BUS_ERROR_MAP段中,里面有三个数组;

如果将bus-error.c编译到动态库,然后test-bus-error.c去连接该动态库,bus-error.c在.so中,有一个BUS_ERROR_MAP段;test-bus-error.c在.exe中,有另一个BUS_ERROR_MAP段,里面只有两个数组。

当使用如下代码打印数组时,就会发现动态连接的输出会少很多(只打印了test-bus-error.c中的两个数组):

extern const sd_bus_error_map __start_BUS_ERROR_MAP[];
extern const sd_bus_error_map __stop_BUS_ERROR_MAP[];

static void dump_mapping_table(void) {
        const sd_bus_error_map *m;

        printf("----- errno mappings ------\n");
        m = __start_BUS_ERROR_MAP;
        while (m < __stop_BUS_ERROR_MAP) {

                if (m->code == BUS_ERROR_MAP_END_MARKER) {
                        m = ALIGN8_PTR(m+1);
                        continue;
                }

                printf("%s -> %i/%s\n", strna(m->name), m->code, strna(errno_to_name(m->code)));
                m ++;
        }
        printf("---------------------------\n");
}

__start_BUS_ERROR_MAP和__stop_BUS_ERROR_MAP分别是段BUS_ERROR_MAP的起始和结尾地址,由GCC负责处理。



目录
相关文章
源文件与模块生成时的文件不同,是否希望调试器使用它?如何解决
源文件与模块生成时的文件不同,是否希望调试器使用它?如何解决
|
1天前
|
存储 编译器 Linux
1.7.1 目标代码文件、可执行文件和库
C编程将源代码文件转换为可执行文件,此过程分为编译与链接两步。首先,编译器将源代码转化为中间代码,再由链接器将其余代码融合,最终生成可执行文件。此方法有助于程序模块化,允许独立编译各模块并在后期使用链接器整合,避免因单一模块变动导致整体重编。同时,链接器还会将用户程序与预编译库代码结合,生成完整程序。目标代码文件在链接前缺少启动代码及库函数,这些由链接器在最后阶段补充完整。
20 7
|
5月前
|
C++ 计算机视觉 Windows
【C++】由于找不到xxx.dll,无法继续执行代码,重新安装程序可能会解决此问题。(解决办法)
【C++】由于找不到xxx.dll,无法继续执行代码,重新安装程序可能会解决此问题。(解决办法)
|
5月前
|
自然语言处理 编译器 调度
深入gcc编译器:C/C++代码如何变为可执行程序
深入gcc编译器:C/C++代码如何变为可执行程序
144 0
|
11月前
|
C++
【c++】c++ 编译链接成的可执行程序 执行时却表示无法找到某个或几个库
问题描述:c++ 程序已经完成了编译链接,但是在执行时,提醒说某个 库 地址找不到,无法启动进程服务。 使用 ldd 命令 查看执行程序 可以看到 存在 某个库 显示 not find
89 0
|
网络协议 C# C++
关于 C#调用一个C/C++dll库运行时实现多个应用(静态变量区分) 的解决方法
关于 C#调用一个C/C++dll库运行时实现多个应用(静态变量区分) 的解决方法
关于 C#调用一个C/C++dll库运行时实现多个应用(静态变量区分) 的解决方法
|
编译器 Linux C语言
在C语言/C++中把资源编译进exe可执行文件,并运行时释放资源
在C语言/C++中把资源编译进exe可执行文件,并运行时释放资源
368 0
编译好的编译ffmpeg又出错:更改输出目录产生各种古怪错误
编译好的编译ffmpeg又出错:更改输出目录产生各种古怪错误
95 0
玩转Makefile | 编译有共用文件的多个程序
玩转Makefile | 编译有共用文件的多个程序
278 0
玩转Makefile | 编译有共用文件的多个程序