API函数库的构造与编程应用

API函数库的构造与编程应用
(刘爱贵 - Aiguille.LIU)

  函数库是一组执行特定功能操作的函数集合,可以独立提供给第三方进行程序开发,通常又称为API(Application Programming Interface),即应用程序编程接口。Linux下,函数库一般有两种形式:静态函数库和动态函数库。应用函数库进行编程时,如果使用静态函数库,则需要将其链接进应用程序中;而使用动态共享库时,则是在程序运行时动态链接和装入的。
  Linux下使用gcc编译工具,可以方便地构造函数库。下面我们以queue.c为例来分别构造静态函数库(.a)和动态共享库(.so):
    (1)静态函数库的构造
        gcc -Wall -c queue.c
        ar rsv libqueue.a queue.o

 (2)动态共享库的构造
  gcc -Wall -fPIC -c queue.c
        gcc -shared -W1,soname,libqueue.so -o libqueue.so queue.o

  假设我们现在应用queue来开发testq.c,则可以分别如下进行编译。
  1、如果queue.c是自行开发,则可以不使用函数库,直接进行编译
    gcc -o testq testq.c queue.c

  2、使用静态函数库
        gcc -o testq testq.c libqueue.a
        gcc -o testq testq.c -lqueue (如果libqueue.a已安装进系统库路径下,且libqueue.so不存在)

  3、使用动态共享库
      gcc -o testq testq.c -lqueue (libqueue.so已安装进系统库路径下,如/lib, /usr/lib, /usr/local/lib等,可在/etc/ld.so.conf中设置)
            gcc -o testq testq.c -L ./ -lqueue (so库放置在其他路径下,可以使用-L选项来指明路径,本例是当前路径)

附程序代码:
/* testq.c */
#include 
" queue.h "

extern  daemonize( const   char   * cmd);

int  main( int  argc,  char   * argv[])
{
        
struct queue q;
        
struct qnode *p;
        
int i;

        
if (argc < 2{
                printf(
"Usage: %s arg1 arg2 ... ", argv[0]);
                exit(
0);
        }

        queue_init(
&q);
        
for (i = 1; i < argc; i++{
                
if ((p = malloc(sizeof(struct qnode))) == NULL) {
                        printf(
"memory alloce error ");
                        exit(
1);
                }
 else {
                        (
char *)p->data = strdup(argv[i]);
                        queue_insert(
&q, p);
                }

        }

        
while(!queue_isempty(&q)) {
                
if ((p = queue_remove(&q)) != NULL) {
                        printf(
"%s ", (char *)p->data);
                        free(p);
                }

        }

        queue_clear(
&q);
        
return 0;
}
/**/ /* queue.h */
#include 
< stdlib.h >
#include 
< pthread.h >

struct  qnode  {
        
struct qnode *prev;
        
struct qnode *next;
        
void *data;
}
;

struct  queue  {
        
struct qnode *head;
        
struct qnode *tail;
        
int qsize;
}
;

void  queue_init( struct  queue  * q);
int  queue_getsize( struct  queue  * q);
int  queue_isempty( struct  queue  * q);
int  queue_clear( struct  queue  * q);
int  queue_insert( struct  queue  * q,  struct  qnode  * node);
struct  qnode  * queue_remove( struct  queue  * q);
struct  qnode  * queue_gethead( struct  queue  * q);
struct  qnode  * queue_gettail( struct  queue  * q);
/* queue.c  */
#include 
" queue.h "

static  pthread_mutex_t  queuelock  =  PTHREAD_MUTEX_INITIALIZER;

void  queue_init( struct  queue  * q)
{
    
if (q != NULL) {
        pthread_mutex_lock(
&queuelock);
        q
->head = q->tail = NULL;
        q
->qsize = 0;
        pthread_mutex_unlock(
&queuelock);
    }

    
return;
}


int  queue_getsize( struct  queue  * q)
{
    
if (q != NULL)
        
return q->qsize;
    
else
        
return -1;
}


int  queue_isempty( struct  queue  * q)
{
    
if (q != NULL)
        
return (q->qsize == 0)? 1 : 0;
    
else 
        
return -1;
}


int  queue_clear( struct  queue  * q)
{
    
struct qnode *p;

    
if (q != NULL) {
        pthread_mutex_lock(
&queuelock);
        
while (q->qsize > 0{
            p 
= queue_remove(q);
            
if (p != NULL)
                free(p);
        }

        pthread_mutex_unlock(
&queuelock);
        queue_init(q);
    }

    
return 0;
}


int  queue_insert( struct  queue  * q,  struct  qnode  * node)
{
    
if (q != NULL) {
        node
->next = NULL;
        node
->prev = q->tail;
        pthread_mutex_lock(
&queuelock);
        
if (q->tail == NULL)
            q
->head = node;
        
else
            q
->tail->next = node;
        q
->tail = node;
        q
->qsize++;
        pthread_mutex_unlock(
&queuelock);
    }

    
return 0;
}


struct  qnode  * queue_remove( struct  queue  * q)
{
    
struct qnode *= NULL;
    
    
if (q != NULL) {
        pthread_mutex_lock(
&queuelock);
        p 
= q->head;
        
if (p != NULL) {
            q
->head = p->next;
            
if (q->head != NULL)
                q
->head->prev = NULL;
            
else 
                q
->tail = NULL;
            q
->qsize--;
        }
 
        pthread_mutex_unlock(
&queuelock);
    }

    
return p;
}


struct  qnode  * queue_gethead( struct  queue  * q)
{
    
if (q != NULL)
        
return q->head;
    
else 
        
return NULL;
}


struct  qnode  * queue_gettail( struct  queue  * q)
{
    
if (q != NULL) 
        
return q->tail;
    
else
        
return NULL;
}

/* The End*/

你可能感兴趣的:(GNU/LINUX,C/C++,编程,api,null,gcc,insert,application)