API函数库的构造与编程应用
(刘爱贵 - Aiguille.LIU)
(刘爱贵 - 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;
}
#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);
#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 *p = 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*/
#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 *p = 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*/