程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言程序靜態庫和動態庫的創建及其應用

C語言程序靜態庫和動態庫的創建及其應用

編輯:關於C語言

在用c寫程序時,很多時候需要存儲一些簡單的數據,如果為此而用mysql數據庫就有些大才小用了,可以把這些數據以結構的形寫入文件,然後再需要時讀取文件,取出數據。

如下是定義函數的源文件和頭文件:

源文件struct.c:

#include "struct.h"
//第一個參數是要寫入的文件名,第二個參數是緩沖區,第三個參數是緩沖區大小,
第四個參數是打開文件流的形態,返回TRUE表示寫入成功,返回FALSE表示寫入失敗
int writeStruct(const char *fileName,char *buffer,int bufferLen,char *mode){
   int ret;
   FILE *fileID = NULL;
   fileID = fopen(fileName,mode);
   if (fileID == NULL){
     perror("fopen");
     goto writeEnd;
   }
   rewind(fileID);
   ret = fwrite(buffer,bufferLen,1,fileID);
   if (ret <= 0){
     perror("fwrite");
     goto writeEnd;
   }
   if (fileID != NULL){
     fclose(fileID);
     fileID = NULL;
   }
   return TRUE;
writeEnd:
   if (fileID != NULL){
     fclose(fileID);
     fileID = NULL;
   }
   return FALSE;
}
//第一個參數是要讀取的文件名,第二個參數是緩沖區,第三個參數是緩沖區大小,第四個參數是打開文件流的形態,返回TRUE表示讀取成功,返回FALSE表示讀取失敗
int readStruct(const char *fileName,char *buffer,int bufferLen,char *mode){
   int ret;
   FILE *fileID = NULL;
   fileID = fopen(fileName,mode);
   if (fileID == NULL){
     perror("fopen");
     goto readEnd;
   }
   rewind(fileID);
   memset(buffer,0,sizeof(buffer));
   ret = fread(buffer,bufferLen,1,fileID);
   if (ret >= 0){
     strcat(buffer,"\0");
   }else{
     perror("fread")  ;
     goto readEnd;
   }
   if (fileID != NULL){
     fclose(fileID);
     fileID = NULL;
   }
   return TRUE;
readEnd:
   if (fileID != NULL){
     fclose(fileID);
     fileID = NULL;
   }
   return FALSE;
}

頭文件struct.h:

#ifndef OWNSTRUCT_H_
#define OWNSTRUCT_H_
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define FALSE 0
#define TRUE 1
//第一個參數是要寫入的文件名,第二個參數是緩沖區,第三個參數是緩沖區大小,
第四個參數是打開文件流的形態,返回TRUE表示寫入成功,返回FALSE表示寫入失敗
int writeStruct(const char *fileName,char *buffer,int bufferLen,char *mode);
//第一個參數是要讀取的文件名,第二個參數是緩沖區,第三個參數是緩沖區大小,
第四個參數是打開文件流的形態,返回TRUE表示讀取成功,返回FALSE表示讀取失敗
int readStruct(const char *fileName,char *buffer,int bufferLen,char *mode);
#endif

為了使用方便,可以把這兩個函數接口定義為動態鏈接庫或靜態鏈接庫。用動態鏈接庫編譯生成的可執行文件需調用.so文件方可正常運行,靈活但稍顯麻煩;用靜態鏈接庫編譯生成的可執行文件可直接運行,不用再調用如.so般的依賴庫文件,簡單但不靈活。

靜態鏈接庫:

1、編譯生成目標文件

gcc -c struct.c

2、創建靜態庫

ar cqs libstruct.a struct.o (順序不能亂)

3、鏈接靜態鏈接庫,生成可執行文件

gcc main.c -static -L. -ltest -o main

動態鏈接庫:

1、編譯成動態鏈接庫

gcc struct.c -fPIC -shared -o libstruct.so

2、鏈接動態鏈接庫,生成可執行文件

gcc main.c -L. -lstruct -o main

3、設置庫文件的環境路徑

1)在bashrc或profile文件裡用LD_LIBRARY_PATH定義,然後用source加載。

2)把庫路徑添加到ld.so.conf文件中,然後用ldconfig加載。

3)ldconfig /home/user/lib,僅能暫時性使用,若下次ldconfig時此目錄下的動態鏈接庫就不能被共享了。

gcc一些參數解析

-shared:指定生成動態鏈接庫。

-static:指定生成靜態鏈接庫。

-fPIC:表示編譯為位置獨立的代碼,用於編譯共享庫。目標文件需要創建成位置無關碼,概念上就是在可執行程序裝載它們的時候,它們可以放在可執行程序的內存裡的任何地方。

-L.:表示要連接的庫在當前目錄中。

-l:指定鏈接時需要的動態庫。編譯器查找動態連接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來確定庫的名稱。

-Wall:生成所有警告信息。

-ggdb:此選項將盡可能的生成gdb的可以使用的調試信息。

-g:編譯器在編譯的時候產生調試信息。

-c:只激活預處理、編譯和匯編,也就是把程序做成目標文件(.o文件)。

-Wl,options:把參數(options)傳遞給鏈接器ld。如果options中間有逗號,就將options分成多個選項,然後傳遞給鏈接程序。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved