当前位置: 首页 > news >正文

__attribute__((__used__)) 和 __attribute__((__section__(“*“ “*“)))的使用

见:haproxy代码

C语言注册函数和调用函数,便于模块化开发和编程。

#include <stdio.h>#ifdef __APPLE__
#define HA_SECTION(s)           __attribute__((__section__("__DATA, " s)))
#define HA_SECTION_START(s)     __asm("section$start$__DATA$" s)
#define HA_SECTION_STOP(s)      __asm("section$end$__DATA$" s)
#else
#define HA_SECTION(s)           __attribute__((__section__(s)))
#define HA_SECTION_START(s)
#define HA_SECTION_STOP(s)
#endif/** Please keep those names short enough, they are used to generate section* names, Mac OS X accepts section names up to 16 characters, and we prefix* them with i_, so stage name can't be more than 14 characters.*/
enum init_stage {STG_PREPARE = 0,      // preset variables, tables, list headsSTG_LOCK,             // pre-initialize locksSTG_REGISTER,         // register static lists (keywords etc)STG_ALLOC,            // allocate required structuresSTG_POOL,             // create poolsSTG_INIT,             // subsystems normal initializationSTG_SIZE              // size of the stages array, must be last
};/* This is the descriptor for an initcall */
struct initcall {void (*const fct)(void *arg1, void *arg2, void *arg3);void *arg1;void *arg2;void *arg3;
#if defined(USE_OBSOLETE_LINKER)void *next;
#endif
};/* declare a symbol as global */
#define __HA_GLOBL(sym)   __asm__(".globl " #sym)
#define HA_GLOBL(sym)     __HA_GLOBL(sym)#define HA_INIT_SECTION(s)  HA_SECTION("i_" # s)#define __DECLARE_INITCALL(stg, linenum, function, a1, a2, a3)     \HA_GLOBL(__start_i_##stg );                                \HA_GLOBL(__stop_i_##stg );                                 \static const struct initcall *__initcb_##linenum           \__attribute__((__used__)) HA_INIT_SECTION(stg) =	   \(stg < STG_SIZE) ? &(const struct initcall) {      \.fct = (void (*)(void *,void *,void *))function,   \.arg1 = (void *)(a1),                              \.arg2 = (void *)(a2),                              \.arg3 = (void *)(a3),                              \} : NULL#define _DECLARE_INITCALL(...) \__DECLARE_INITCALL(__VA_ARGS__)#define INITCALL0(stage, function)  \_DECLARE_INITCALL(stage, __LINE__, function, 0, 0, 0)/* Declare func */
#define DECLARE_INIT_SECTION(stg)                                                   \extern __attribute__((__weak__)) const struct initcall *__start_i_##stg HA_SECTION_START("i_" # stg); \extern __attribute__((__weak__)) const struct initcall *__stop_i_##stg  HA_SECTION_STOP("i_" # stg)#define FOREACH_INITCALL(p,stg)                                               \for ((p) = &(__start_i_##stg); (p) < &(__stop_i_##stg); (p)++)#define RUN_INITCALLS(stg)                                                     \do {                                                                   \const struct initcall **ptr;                                   \if (stg >= STG_SIZE)                                           \break;                                                 \FOREACH_INITCALL(ptr, stg)                                     \(*ptr)->fct((*ptr)->arg1, (*ptr)->arg2, (*ptr)->arg3); \} while (0)/* register func1 */
static void _do_register_func1(void)
{printf("TEST: _do_register_func1()\n");
}
#if 0
__asm__(".globl " "__start_i_STG_REGISTER"); 
__asm__(".globl " "__stop_i_STG_REGISTER"); 
static const struct initcall *__initcb_405 __attribute__((__used__)) __attribute__((__section__("i_" "STG_REGISTER"))) = (STG_REGISTER < STG_SIZE) ? &(const struct initcall) 
{ .fct = (void (*)(void *,void *,void *))_do_register, .arg1 = (void *)(0), .arg2 = (void *)(0), .arg3 = (void *)(0), 
} : ((void *)0);
#endif
INITCALL0(STG_REGISTER, _do_register_func1);/* register func2 */
static void _do_register_func2(void)
{printf("TEST: _do_register_func2()\n");
}
INITCALL0(STG_REGISTER, _do_register_func2);/* register func3 */
static void _do_register_func3(void)
{printf("TEST: _do_register_func3()\n");
}
INITCALL0(STG_REGISTER, _do_register_func3);/* declare func1, func2, func3 */
DECLARE_INIT_SECTION(STG_REGISTER);int main(int argc, char *const argv[])
{/* call func1, func2, func3 */RUN_INITCALLS(STG_REGISTER);printf("hello world\n");return 0;
}

编译和运行:

ubuntu@dev:test-06$ gcc test1.c
ubuntu@dev:test-06$ ./a.out 
TEST: _do_register_func1()
TEST: _do_register_func2()
TEST: _do_register_func3()
hello world

不使用__attribute__((used)) 和 attribute((section(““ ““)))

#include <stdio.h>/* register func1 */
static void _do_register_func1(void)
{printf("TEST: _do_register_func1()\n");
}/* register func2 */
static void _do_register_func2(void)
{printf("TEST: _do_register_func2()\n");
}/* register func3 */
static void _do_register_func3(void)
{printf("TEST: _do_register_func3()\n");
}int main(int argc, char *const argv[])
{/* call func1, func2, func3 */_do_register_func1();_do_register_func2();_do_register_func3();printf("hello world\n");return 0;
}
http://www.lryc.cn/news/220313.html

相关文章:

  • webgoat-(A1)SQL Injection
  • Flink的API分层、架构与组件原理、并行度、任务执行计划
  • Transformer:开源机器学习项目,上千种预训练模型 | 开源日报 No.66
  • Corel VideoStudio 会声会影2024剪辑中间的视频怎么删 剪辑中音乐太长怎么办
  • 数据结构初阶---复杂度的OJ例题
  • Prometheus|云原生|grafana的admin用户密码重置备忘记录
  • [hive]中的字段的数据类型有哪些
  • 第六章 树【数据结构和算法】【精致版】
  • 第九章:Dynamic Symbolic Execution
  • 在搜索引擎中屏蔽csdn
  • Linux开发工具的使用(vim、gcc/g++ 、make/makefile)
  • MySQL(10):创建和管理表
  • Python赋值给另一个变量且不改变原变量
  • PHP进销存ERP系统源码
  • npm i 报错:Cannot read properties of null (reading ‘refs‘)
  • C#学习中关于Visual Studio中ctrl+D快捷键(快速复制当前行)失效的解决办法
  • 银河E8,吉利版Model 3:5米大车身、45寸大屏、首批8295座舱芯
  • 技术分享 | 被测项目需求你理解到位了么?
  • [MRCTF2020]你传你呢1
  • 一些对程序员有用的网站
  • 小程序使用echarts(超详细教程)
  • js控制输入框中的光标位置
  • Openssl生成证书-nginx使用ssl
  • Go语言实现数据结构栈和队列
  • 【vscode】Window11环境下vscode使用Fira Code字体【教程】
  • Sandcastle生成文档
  • P1368 【模板】最小表示法
  • 【Hive】内部表(Managed Table)和外部表(External Table)相关知识点
  • 算法通关村第十四关白银挑战——堆的经典算法题
  • selenium自动化测试入门 —— python unittest单元测试框架