模块化代码(封装 __attribute__ constructor&destructor )

28 篇文章 0 订阅

constructor / destructor

意思是: 构造器和析构器;constructor修饰的函数会在main函数之前执行,destructor修饰的函数会在程序exit前调用.
示例如下:

int main(int argc, char * argv[]) {
    @autoreleasepool {
        NSLog(@"main");
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}
 
__attribute__((constructor))
void  before(){
    NSLog(@"before main");
}
 
__attribute__((destructor))
void  after(){
    NSLog(@"after main");
}
 
//在viewController中调用exit
- (void)viewDidLoad {
    [super viewDidLoad];
 
    exit(0);
}
输出如下:
 
2016-07-21 21:49:17.446 Study[14162:5415982] before main
2016-07-21 21:49:17.447 Study[14162:5415982] main
2016-07-21 21:49:17.534 Study[14162:5415982] after main

因此可以根据每一个模块封装成对应的加载接口和卸载接口。

太懒了,直接贴代码。。

版本一,初步封装

#include <stdio.h>

typedef struct ks_module_info
{
	const char* name;
	unsigned char priority;
	int (*load)(void);
	int (*unload)(void);
}ks_module_info;

void ks_module_register(const struct ks_module_info *info);
void ks_module_unregister(const struct ks_module_info *info);

void ks_module_register(const struct ks_module_info* info)
{
	printf("##### before main, ks_module_register ######\n");
    info->load();
}
void ks_module_unregister(const struct ks_module_info* info)
{
	printf("##### after main, ks_module_unregister ######\n");
    info->unload();
}

#define KS_MODULE_INFO(name, load_pri, load_func, unload_func)	\
	static struct ks_module_info __mod_info = {	\
		name,					\
		load_pri,				\
		load_func,				\
		unload_func,			\
	};							\
	static void  __attribute__((constructor)) __reg_module(void) \
	{ \
		ks_module_register(&__mod_info); \
	} \
	static void  __attribute__((destructor)) __unreg_module(void) \
	{ \
		ks_module_unregister(&__mod_info); \
	}


    
#define MD_FAILOVER_NAME  "mod_failover"
enum MD_PRIORITY
{
	MD_DAEMON_PRIORITY = 1,
	MD_FAILOVER_PRIORITY,
};

static int unload_module(void)
{
    printf("########### unload module ########\n");
    return 0;
}

static int load_module(void)
{
    printf("########### load module ########\n");
	return 0;
}

    
int main(int argc,char **argv)
{   
    printf("hello world!\n");
    return 0;
}

KS_MODULE_INFO(MD_FAILOVER_NAME, MD_FAILOVER_PRIORITY, load_module, unload_module);

版本二,实际项目中可能运用的方法

工程文件

kscore.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "kscore.h"
#include "ksstd.h"
#include "ksmodule.h"


#define MAX_STR_LEN 64

static void load_modules()
{
	int i = 0;
    int modulecount = 0;
	struct ks_module_info *modules = NULL;
	
	ks_get_modules(&modules, &modulecount);
	if (!modules || !modulecount)
	{
		ksdebug(DEBUG_ERR, "get modules fail.");
		return;
	}

	for (i = 0; i < modulecount; i++)
	{
		if (!modules[i].name)
			continue;
		modules[i].load();
	}
}

static void unload_modules()
{
	int i;
    int modulecount = 0;
	struct ks_module_info *modules = NULL;
	
	ks_get_modules(&modules, &modulecount);
	if (!modules || !modulecount)
		return;
	
	i = modulecount-1;
	for ( ; i >= 0; i--)
	{
		if (!modules[i].name) 
			continue;
		modules[i].unload();
	}	
}

//
//
int ks_core_start(int verify)
{
	load_modules();	
	return 0;
}

int ks_core_stop()
{
	unload_modules();
	
	return 0;
}

int ks_core_unload_module(int priority)
{
	int i, modulecount = 0;
	struct ks_module_info *modules = NULL;
	
    ksprintf("==================ks_core_unload_module:%d====================", priority);
	ks_get_modules(&modules, &modulecount);
	if (!modules || !modulecount)
		return -1;
	
	i = modulecount-1;
	for ( ; i >= 0; i--)
	{
		if (!modules[i].name) 
			continue;
		if(priority == modules[i].priority)
			modules[i].unload();
	}	
	
	return 0;
}

kscore.h

#ifndef _KS_CORE_H_
#define _KS_CORE_H_


#ifdef __cplusplus
extern "C"
{
#endif

int ks_core_start();
int ks_core_stop();
int ks_core_unload_module(int priority);

#ifdef __cplusplus
}
#endif

#endif

ksdefs.h

#ifndef _KS_CORE_H_
#define _KS_CORE_H_


#ifdef __cplusplus
extern "C"
{
#endif

int ks_core_start();
int ks_core_stop();
int ks_core_unload_module(int priority);

#ifdef __cplusplus
}
#endif

#endif

ksmodule.c

#include "ksmodule.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ksstd.h"

static int ks_module_debug = 0;
static int global_md_cnt = 0;
static struct ks_module_info global_modules[MAX_KS_MODULE] = {{0}};

static struct ks_module_info* find_module(const char* name)
{
	int i = 0;
	for ( ; i < MAX_KS_MODULE; i++)
	{
		if (global_modules[i].name && strcasecmp(global_modules[i].name, name)==0) 
			return &global_modules[i];
	}
	return NULL;
}

static void insert_module_info(struct ks_module_info modules[MAX_KS_MODULE], struct ks_module_info* info)
{
	int idx = 0;
	for ( ; idx < global_md_cnt; idx++)
	{
		if (info->priority > modules[idx].priority)
			break;
	}
	int move = global_md_cnt;
	for ( ; move > idx; move--)
	{
		memcpy(modules+move, modules+move-1, sizeof(struct ks_module_info));
	}
	memcpy(modules+idx, info, sizeof(struct ks_module_info));
	global_md_cnt++;
    
    if (ks_module_debug)
    {
        int i = 0;
        for ( ; i < global_md_cnt; i++)
        {
            ksprintf("module-%d name:%s", i+1, modules[i].name);
        }	
    }	
}

void ks_module_register(const struct ks_module_info* info)
{
	if (!info || !info->name) 
		return;
	if (find_module(info->name)) 
		return;
	if (global_md_cnt >= MAX_KS_MODULE)
		return;
	int i = 0;
	for ( ; i < MAX_KS_MODULE; i++)
	{
		if (global_modules[i].name)
			continue;
		insert_module_info(global_modules, (struct ks_module_info*)(info));
		break;
	}
}
void ks_module_unregister(const struct ks_module_info* info)
{
	if (!info || !info->name) 
		return;
	struct ks_module_info* mod = find_module(info->name);
	if (!mod) 
		return;
	memset(mod, 0, sizeof(struct ks_module_info));
	global_md_cnt--;
}

int ks_get_modules(struct ks_module_info **modules, int *capability)
{
	if (!modules || !capability) 
		return -1;
	*modules	= global_modules;
	*capability	= global_md_cnt;
	return 0;
}

ksmodule.h

/* 
 * Filename:      	ksmodule
 * Created at:    	2019.02.26
 * Description:   	module controller.
 * Author:        	ks
 * Copyright (C)  	xxl
 * ****************************************************************/
#ifndef _KS_MODULE_H_
#define _KS_MODULE_H_

#ifdef __cplusplus
extern "C"
{
#endif

#define KS_MODULE_CONF  "/mnt/nand/etc/modules.conf" 
#define MAX_KS_MODULE   4


enum MD_PRIORITY
{
	MD_PRIORITY_LOG         = 1,
	MD_PRIORITY_SEARCH      = 2,
	MD_PRIORITY_SYSCONF     = 3,
	MD_PRIORITY_FAILOVER    = 4,
};


#define MD_NAME_LOG         "log"
#define MD_NAME_SEARCH      "search"
#define MD_NAME_SYSCONF		"sysconf"
#define MD_NAME_FAILOVER    "failover"


typedef struct ks_module_info
{
	const char* name;
	unsigned char priority;
	int (*load)(void);
	int (*unload)(void);
}ks_module_info;

void ks_module_register(const struct ks_module_info *info);
void ks_module_unregister(const struct ks_module_info *info);

#define KS_MODULE_INFO(name, load_pri, load_func, unload_func)	\
	static struct ks_module_info __mod_info = {	\
		name,					\
		load_pri,				\
		load_func,				\
		unload_func,			\
	};							\
	static void  __attribute__((constructor)) __reg_module(void) \
	{ \
		ks_module_register(&__mod_info); \
	} \
	static void  __attribute__((destructor)) __unreg_module(void) \
	{ \
		ks_module_unregister(&__mod_info); \
	}

int ks_get_modules(struct ks_module_info **modules, int *capability);

#ifdef __cplusplus
}
#endif

#endif

ksstd.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "ksstd.h"

void time_to_string(int ntime, char stime[32])
{
	struct tm temp;

	localtime_r((long*)&ntime, &temp);
	snprintf(stime, 32, "%4d-%02d-%02d %02d:%02d:%02d", 
		temp.tm_year + 1900, temp.tm_mon + 1, temp.tm_mday, temp.tm_hour, temp.tm_min, temp.tm_sec);
}

void time_to_string_ks(char stime[32])
{
	struct tm temp;
	struct timeval tv;
	gettimeofday(&tv, NULL);
	localtime_r(&tv.tv_sec, &temp);
	snprintf(stime, 32, "%4d-%02d-%02d %02d:%02d:%02d.%03d", 
		temp.tm_year + 1900, temp.tm_mon + 1, temp.tm_mday, temp.tm_hour, temp.tm_min, temp.tm_sec,(int)(tv.tv_usec/1000));
}

ksstd.h

#ifndef _KS_STD_H_
#define _KS_STD_H_

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C"
{
#endif

void time_to_string(int ntime, char stime[32]);
void time_to_string_ks(char stime[32]);

/* Word color define */
#define YELLOW			"\033[0;33m"	// yellow
#define GRAY 			"\033[2;37m"
#define DGREEN 			"\033[1;32m"
#define GREEN 			"\033[0;32m"
#define DARKGRAY 		"\033[0;30m"
//#define BLACK 		"\033[0;39m"
#define BLACK 			"\033[2;30m" 	// not faint black
#define NOCOLOR 		"\033[0;39m \n"
#define CLRCOLOR		"\033[0;39m "
//#define NOCOLOR 		"\033[0m \n"
#define BLUE 			"\033[1;34m"
#define DBLUE 			"\033[2;34m"	
#define RED 			"\033[0;31m"
#define BOLD 			"\033[1m"
#define UNDERLINE 		"\033[4m"
#define CLS 			"\014"
#define NEWLINE 		"\r\n"


#define DEBUG_LEVEL_DEFAULT 0xffffffff
extern unsigned int global_debug_mask;
typedef void (*hook_print)(char* format, ...);
extern hook_print global_debug_hook;
#define ERR_LOG_PATH	"./err_log.txt"

enum DEBUG_LEVEL
{
	DEBUG_ERR = 0x01,
	DEBUG_WRN = 0x02,
	DEBUG_INF = 0x04,
	DEBUG_GUI = 0x08,
	DEBUG_POE = 0X10,
};



#define _log_err(level, prefix, format, ...) \
	do{\
		if(global_debug_mask & level){\
			char stime[32] = {0};\
			char log[1024] = {0};\
			char cmd[128] = {0};\
			int filesize = -1;\
			FILE * hfile = NULL;\
			hfile = fopen(ERR_LOG_PATH, "a");\
			if(hfile){\
				fseek(hfile, 0L, SEEK_END);\
    			filesize = ftell(hfile);\
				time_to_string(time(0), stime);\
				snprintf(log, sizeof(log), "[%s%s %d==func:%s file:%s line:%d]==" format "\n", \
				prefix, stime, getpid(), __func__, __FILE__, __LINE__, ##__VA_ARGS__); \
				fwrite(log, 1, strlen(log), hfile);\
				fflush(hfile);\
				fclose(hfile);\
				snprintf(cmd, sizeof(cmd), "rm -rf %s", ERR_LOG_PATH);\
				if(filesize > 1024*1024)\
					system(cmd);\
			}\
		}\
    }while(0);
    
#define mslogerr(level, format, ...) \
	if(level == DEBUG_ERR){\
		_debug(level,  "ERR:",RED format CLRCOLOR, ##__VA_ARGS__)\
		_log_err(level, "ERR:", format, ##__VA_ARGS__)\
	}else if(level == DEBUG_WRN)\
		_log_err(level, "WRN:", format, ##__VA_ARGS__)\
	else\
		_log_err(level, "INF:", format, ##__VA_ARGS__)

        
#define _debug(level, prefix, format, ...) \
	do{\
		if(global_debug_mask & level){\
			char stime[32] = {0};\
			time_to_string_ks(stime);\
			printf("[%s%s %d==func:%12s file:%12s line:%6d]==" format "\n", \
			prefix, stime, getpid(), __func__, __FILE__, __LINE__, ##__VA_ARGS__); \
            if(global_debug_hook)\
				global_debug_hook("[%s%s %d==func:%12s file:%12s line:%6d]==" format "\n",\
				prefix, stime, getpid(), __func__, __FILE__, __LINE__, ##__VA_ARGS__);\
		}\
    }while(0);		

#define ksdebug(level, format, ...) \
	do { \
		switch(level) \
		{ \
		case DEBUG_ERR: \
			_debug(level,  "ERR:",RED format CLRCOLOR, ##__VA_ARGS__); \
			_log_err(level, "ERR:", format, ##__VA_ARGS__); \
			break; \
		case DEBUG_WRN: \
			_debug(level, "WRN:",YELLOW format CLRCOLOR, ##__VA_ARGS__); \
			break; \
		case DEBUG_GUI: \
			_debug(level, "GUI:",GREEN format CLRCOLOR, ##__VA_ARGS__); \
			break; \
		default: \
			_debug(level, "INF:", format, ##__VA_ARGS__); \
			break; \
		} \
	}while(0)		
	

#define ksprintf(format, ...) \
    do{\
		char stime[32] = {0};\
		time_to_string(time(0), stime);\
		printf("[%s %d==func:%s file:%s line:%d]==" format "\n", \
		stime, getpid(), __func__, __FILE__, __LINE__, ##__VA_ARGS__); \
    }while(0)
        
    
#ifdef __cplusplus
}
#endif


#endif 

main.c

#include <signal.h>
#include <string.h>
#include <stdio.h>
#include "ksstd.h"
//#include "kscore.h"

int g_exitcore = 0;
unsigned int global_debug_mask = DEBUG_LEVEL_DEFAULT;
hook_print global_debug_hook = 0;
extern int global_record_run;
static int global_module_debug = 0;

static void signal_handler(int signal)
{
	if(signal != SIGPIPE)
		printf("mscore recv signal %d\n", signal);
	switch(signal)
	{
		case SIGINT:
		case SIGTERM:
		case SIGKILL:
			g_exitcore = 1;
			break;
		case SIGUSR2:
			g_exitcore = 2;
			break;
		case SIGPIPE:
			break;
		default:
			break;
	}	
}

static void signal_backtrace(int signo)
{
	time_t t = time(NULL);
	
	if(signo == 11)
	{
		printf("kscore received signal: %d, backtrace stack at time: %s...\n",signo, ctime(&t));
		ksdebug(DEBUG_ERR, "kscore received signal: %d, backtrace stack at time: %s...\n",signo, ctime(&t));
	}
	
	exit(0);
}

static void set_core_signal()
{
	signal(SIGINT,  signal_handler);	//2//
	signal(SIGTERM, signal_handler);	//15
	signal(SIGKILL, signal_handler);	//9
	signal(SIGPIPE, signal_handler);	//13
	signal(SIGUSR2, signal_handler);	//12
	
	signal(SIGSEGV, signal_backtrace);	//11
	signal(SIGBUS, signal_backtrace);	// 7
	signal(SIGILL, signal_backtrace);	// 4
	signal(SIGSTKFLT, signal_backtrace);// 16
	signal(SIGFPE, signal_backtrace);	// 8
	signal(SIGABRT, signal_backtrace);	//6
}

 
int main(int argc,char **argv)
{   
    ksprintf("hello world!");
    ks_core_start(1);

    set_core_signal();
    
    //maybe run a thread
    while (1)
    {
        if (g_exitcore)
        {
            break;
        }
        
        usleep(100*1000);//100ms
    }

    ks_core_stop();
    return 0;
}

mod_failover.c

/* 
 * Filename:      	mod_failover
 * Created at:    	2019.02.26
 * Description:        failover module
 * Author:        	ks
 * Copyright (C)  	xxl
 * *******************************************************/

#include <string.h>
#include "ksmodule.h"
#include "ksstd.h"


struct md_failover_conf
{
	int loaded;
	int debug;
};
static struct md_failover_conf g_failover_conf = {0};

static int init_module()
{
	return 0;
}

static int uninit_module()
{
	return 0;
}


static int load_module(void)
{
	if(g_failover_conf.loaded)
		return 1;

	ksprintf("====load module:%s====", MD_NAME_FAILOVER);

	g_failover_conf.loaded = 1;
	g_failover_conf.debug = 0;
	
	if(init_module() != 0)
	{
		ksdebug(DEBUG_WRN, "load module:%s failed.", MD_NAME_FAILOVER);
		g_failover_conf.loaded = 0;
		return -1;
	}

	return 0;
}

static int unload_module(void)
{
	if (g_failover_conf.loaded == 0)
		return 1;
	g_failover_conf.loaded = 0;

	uninit_module();
	ksprintf("====unload %s success.====", MD_NAME_FAILOVER);

	return 0;
}

KS_MODULE_INFO(MD_NAME_FAILOVER, MD_PRIORITY_FAILOVER, load_module, unload_module);

mod_log.c

/* 
 * Filename:      	mod_log
 * Created at:    	2019.02.26
 * Description:        log module
 * Author:        	ks
 * Copyright (C)  	xxl
 * *******************************************************/

#include <string.h>
#include "ksmodule.h"
#include "ksstd.h"


struct md_log_conf
{
	int loaded;
	int debug;
};
static struct md_log_conf g_log_conf = {0};

static int init_module()
{
	return 0;
}

static int uninit_module()
{
	return 0;
}


static int load_module(void)
{
	if(g_log_conf.loaded)
		return 1;

	ksprintf("====load module:%s====", MD_NAME_LOG);

	g_log_conf.loaded = 1;
	g_log_conf.debug = 0;
	
	if(init_module() != 0)
	{
		ksdebug(DEBUG_WRN, "load module:%s failed.", MD_NAME_LOG);
		g_log_conf.loaded = 0;
		return -1;
	}

	return 0;
}

static int unload_module(void)
{
	if (g_log_conf.loaded == 0)
		return 1;
	g_log_conf.loaded = 0;

	uninit_module();
	ksprintf("====unload %s success.====", MD_NAME_LOG);

	return 0;
}

KS_MODULE_INFO(MD_NAME_LOG, MD_PRIORITY_LOG, load_module, unload_module);

mod_search.c

/* 
 * Filename:      	mod_search
 * Created at:    	2019.02.26
 * Description:        search module
 * Author:        	ks
 * Copyright (C)  	xxl
 * *******************************************************/

#include <string.h>
#include "ksmodule.h"
#include "ksstd.h"


struct md_search_conf
{
	int loaded;
	int debug;
};
static struct md_search_conf g_search_conf = {0};

static int init_module()
{
	return 0;
}

static int uninit_module()
{
	return 0;
}


static int load_module(void)
{
	if(g_search_conf.loaded)
		return 1;

	ksprintf("====load module:%s====", MD_NAME_SEARCH);
    //int *x = NULL;
    //*x = 1;
	g_search_conf.loaded = 1;
	g_search_conf.debug = 0;
	
	if(init_module() != 0)
	{
		ksdebug(DEBUG_WRN, "load module:%s failed.", MD_NAME_SEARCH);
		g_search_conf.loaded = 0;
		return -1;
	}

	return 0;
}

static int unload_module(void)
{
	if (g_search_conf.loaded == 0)
		return 1;
	g_search_conf.loaded = 0;

	uninit_module();
	ksprintf("====unload %s success.====", MD_NAME_SEARCH);

	return 0;
}

KS_MODULE_INFO(MD_NAME_SEARCH, MD_PRIORITY_SEARCH, load_module, unload_module);

mod_sysconf.c

/* 
 * Filename:      	mod_sysconf
 * Created at:    	2019.02.26
 * Description:        sysconf module
 * Author:        	ks
 * Copyright (C)  	xxl
 * *******************************************************/

#include <string.h>
#include "ksmodule.h"
#include "ksstd.h"


struct md_sysconf_conf
{
	int loaded;
	int debug;
};
static struct md_sysconf_conf g_sysconf_conf = {0};

static int init_module()
{
	return 0;
}

static int uninit_module()
{
	return 0;
}


static int load_module(void)
{
	if(g_sysconf_conf.loaded)
		return 1;

	ksprintf("====load module:%s====", MD_NAME_SYSCONF);

	g_sysconf_conf.loaded = 1;
	g_sysconf_conf.debug = 0;
	
	if(init_module() != 0)
	{
		ksdebug(DEBUG_WRN, "load module:%s failed.", MD_NAME_SYSCONF);
		g_sysconf_conf.loaded = 0;
		return -1;
	}

	return 0;
}

static int unload_module(void)
{
	if (g_sysconf_conf.loaded == 0)
		return 1;
	g_sysconf_conf.loaded = 0;

	uninit_module();
	ksprintf("====unload %s success.====", MD_NAME_SYSCONF);

	return 0;
}

KS_MODULE_INFO(MD_NAME_SYSCONF, MD_PRIORITY_SYSCONF, load_module, unload_module);


运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值