在用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分成多個選項,然後傳遞給鏈接程序。