Lunix下生成動態庫文件:
之前已經介紹了依靠makefile文件實現可執行文件,下面說下在源文件中指定加載的動態庫文件;
一. 源碼文件:
datetime.h:
#ifndef __DATETIME_H
#define __DATETIME_H
/* 日期結構 */
typedef struct
{
int year;
int mon;
int day;
}DATETYPE;
/* 時間結構 */
typedef struct
{
char hour;
char min;
char sec;
}TIMETYPE;
/* 函數原型說明 */
#ifdef SHARED
int (*getdate)(DATETYPE *d);
#else
int getdate(DATETYPE *d);
#endif
#ifdef SHARED
int (*gettime)(TIMETYPE *t);
#else
int gettime(TIMETYPE *t);
#endif
#endif
getdate.c:
#include "time.h"
#include "datetime.h"
int getdate(DATETYPE *d)
{
long ti;
struct tm *tm;
time(&ti);
tm=localtime(&ti);
d->year=tm->tm_year+1900;
d->mon=tm->tm_mon+1;
d->day=tm->tm_mday;
}
gettime.c:
#include "time.h"
#include "datetime.h"
int gettime(TIMETYPE *t)
{
long ti;
struct tm *tm;
time(&ti);
tm=localtime(&ti);
t->hour=tm->tm_hour;
t->min=tm->tm_min;
t->sec=tm->tm_sec;
}
dy.c:
#include "stdio.h" /* 包含標准輸入輸出文件 */
#include "dlfcn.h" /* 包含動態鏈接功能接口文件 */
#define SOFILE "../lib/libmy.so" /* 指定動態鏈接庫名稱 */
#define SHARED /* 定義宏,確認共享,以便引用動態函數 */
#include "datetime.h" /* 包含用戶接口文件 */
main()
{
DATETYPE d;
TIMETYPE t;
void *dp;
char *error;
puts("獲取當前時間");
dp=dlopen(SOFILE,RTLD_LAZY); /* 打開動態鏈接庫 */
if (dp==NULL) /* 若打開失敗則退出 */
{
fputs(dlerror(),stderr);
exit(1);
}
getdate=dlsym(dp,"getdate"); /* 定位取日期函數 */
error=dlerror(); /* 檢測錯誤 */
if (error) /* 若出錯則退出 */
{
fputs(error,stderr);
exit(1);
}
getdate(&d); /* 調用此共享函數 */
printf("當前日期: %04d-%02d-%02d\n",d.year,d.mon,d.day);
gettime=dlsym(dp,"gettime"); /* 定位取時間函數 */
error=dlerror(); /* 檢測錯誤 */
if (error) /* 若出錯則退出 */
{
fputs(error,stderr);
exit(1);
}
gettime(&t); /* 調用此共享函數 */
printf("當前時間: %02d:%02d:%02d\n",t.hour,t.min,t.sec);
dlclose(dp); /* 關閉共享庫 */
exit(0); /* 成功返回 */
}
二.對源文件闡述:
dy.c文件中:
- #include "dlfcn.h" /* 包含動態鏈接功能接口文件 */
- #define SOFILE "../lib/libmy.so" /* 指定動態鏈接庫名稱 */
- dp=dlopen(SOFILE,RTLD_LAZY); /* 打開動態鏈接庫 */
- error=dlerror();
- dlclose(dp); /* 關閉共享庫 */
以上是在源文件中鏈接動態庫文件常用命令;
三.Makefile文件:
#*****************************************************************************
# Copyright :
#
# Author : huochangjun
# Date : 2012-08-15
# Version : Demo1
# Description : Demo
#
#****************************************************************************/
SHELL = /bin/sh
LIB_DIR = /cbs/lhbb/hcj/test/lib/
BIN_DIR = /cbs/lhbb/hcj/test/bin/
OBJECT_DIR = /cbs/lhbb/hcj/test/obj/
APP_DIR = /cbs/lhbb/hcj/test/testapp/
$(shell mkdir -p ${LIB_DIR})
$(shell mkdir -p ${BIN_DIR})
$(shell mkdir -p ${OBJECT_DIR})
RM = rm -fr
#****************************************************************************
CC = gcc
SHARED = -shared -o
FPIC = -fPIC -c
RDY = -rdynamic -s
SRC_OBJECT = $(APP_DIR)getdate.c $(APP_DIR)gettime.c
H_OBJECT = $(APP_DIR)datetime.h
OBJECT = getdate.o gettime.o
DY_SRC_OBJECT = $(APP_DIR)dy.c
DY_OBJECT=dy.o
LIB_OBJECT = libmy.so
BIN_OBJECT = dy
#****************************************************************************
.PHONY:all
all:$(LIB_OBJECT) $(BIN_OBJECT)
$(LIB_OBJECT):$(OBJECT)
$(CC) $(OBJECT) $(SHARED) -fPIC -o $(LIB_OBJECT)
mv $(LIB_OBJECT) $(LIB_DIR)
$(OBJECT):$(SRC_OBJECT) $(H_OBJECT)
$(CC) $(FPIC) $(SRC_OBJECT)
$(BIN_OBJECT):$(DY_OBJECT)
$(CC) $(RDY) -o $(BIN_OBJECT) $(OBJECT_DIR)$(DY_OBJECT) -ldl -L$(LIB_DIR) -lmy
mv $(BIN_OBJECT) $(BIN_DIR)
$(DY_OBJECT):$(DY_SRC_OBJECT)
$(CC) -c $(DY_SRC_OBJECT) -o $(DY_OBJECT)
mv $(OBJECT) $(DY_OBJECT) $(OBJECT_DIR)
clean:
$(RM) $(LIB_DIR) $(BIN_DIR) $(OBJECT_DIR)
四.對makefile文件的簡單闡述:
基本的變量賦值在生成靜態庫文件已經介紹了,這邊就不再重復了。
和上一篇中加載不同的是,編譯的命令不同:
1. $(CC) $(RDY) -o $(BIN_OBJECT) $(OBJECT_DIR)$(DY_OBJECT) -ldl -L$(LIB_DIR) -lmy
---- $(RDY):-rdynamic 指定輸出文件為動態鏈接方式;
–s 指定刪除目標文件中的符號表
-ldl 裝配程序ld要裝載dl函數庫;