openssl MAIN PROG

###################################################################
# openssl MAIN PROG
# 20060313 by daineng@nj.cpsecure
# Last Modified @ 20060404
###################################################################

这个方法的主要作用是将一下独立的程序(main)在适当的时候作为一个函数
结合到一个更大的程序中去(MONOLITH)。

定义方式如下:

    在{openssl}/apps/apps.h文件中

        #ifndef MONOLITH

            #define MAIN(a,v)    main(a,v)

            #ifndef NON_MAIN
                CONF *config=NULL;
                BIO *bio_err=NULL;
            #else
                extern CONF *config;
                extern BIO *bio_err;
            #endif

        #else

            #define MAIN(a,v)    PROG(a,v)
            extern CONF *config;
            extern char *default_config_file;
            extern BIO *bio_err;

        #endif

    再看可以产生独立小程序的源程序文件,如{openssl}/apps/ca.c。在开
    始有以下定义:

        #undef PROG
        #define PROG ca_main

    在下面有如下定义:

        int MAIN(int, char **);

        int MAIN(int argc, char **argv)
        {
            ....
        }

    在下面有如下定义:
    最后看个大程序,它是{openssl}/apps/openssl.c,这里其实没有什么
    'define'或'undef'语句,但有下面这样的包含文件:

        #include "progs.h"

    下面我们来看这个{openssl}/apps/progs.h文件:

    首先是一堆函数的声明,包含ca_main:

        ......
        extern int ca_main(int argc,char *argv[]);
        ......

    紧接着是一个结构:

        typedef struct {
            int type;
            const char *name;
            int (*func)(int argc, char *argv[]);
        } FUNCTION;

    type是函数类型,类型定义在这个结构定义之上;name是上面声明的函
    数名称,对于ca_main来说就是'ca';func就是函数本身了。

    下面定义了这个结构的数组,将上面声明的所有函数包含进去:

        FUNCTION functions[] = {
            ......
            {FUNC_TYPE_GENERAL, "ca", ca_main},
            ......
            {0, NULL, NULL}
        };

    openssl.c就可以利用这个functions数组来以函数的方式使用所有的小
    程序,这点在{openssl}/apps/openssl.h中可以看见,典型的就是遍历
    这个数组,找到需要的函数类型。

编译小程序的情况:

    在我们编译小程序的时候,所有的MAIN被直接替换为main。没有任何一
    个地方会出现PROG名字,所以在每个小程序的源文件中关于PROG的设置
    将产生不了任何作用。

编译大程序的情况:

    当我们需要编译大程序的时候,定义MONOLITH,所有的MAIN(a, v)在预
    编译的时候就被替换为PROG(a, v),在每个源文件中,由于对PROG的独
    特的定义,PROG又会被替换成一个独特的函数名称。
    如在ca.c文件中,MAIN就会被替换成这样:

        int ca_main(int, char **)

    在openssl.c中,就可以以ca_main子程序的方式来使用这个ca程序。
    
其他:

    这里还出现了一个关于NON_MAIN的预编译选项。它的出现是由于在程序
    中有一些都要使用到的变量,无论是在大程序还是在小程序中,像上面
    的 config 和 bio_err。

    在编译小程序时,由于没有定义 MONOLITH 和 NON_MAIN,在apps.h中
    对 config 和 bio_err 的定义就会是这样:

        CONF *config=NULL;
        BIO *bio_err=NULL;

    这个时候注意到 apps.h 是 apps.c 的头文件,如果不做任何处理的话
    我们将得到在多个obj文件中重复定义的错误,所以在apps.c中#include
    被写成这样:

        #define NON_MAIN
        #include "apps.h"
        #undef NON_MAIN

    这时对于apps.c来说,config 和 bio_err 的定义就是:

        extern CONF *config;
        extern BIO *bio_err;

    如果是编译大程序,由于 MONOLITH 已被定义,config 和 bio_err 在
    apps.h中定义都是 extern 型的,这两个变量被定义在openssl.c源文
    件中:

        #ifdef MONOLITH
        CONF *config=NULL;
        BIO *bio_err=NULL;
        #endif

总结:

    就像在开头说的那样,如果我们独立的编写一些小程序,在最后会合并
    到一个大程序中的话,我们就可以使用这样的方式。但我觉得也有不好
    的地方,int (*func)(int argc, char *argv[])这样的函数接口似乎不
    是很妥当。

    看情况用着吧。 ;-)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值