庫的創建和調用
假如,你有一個龐大的工程,如果把整個數百兆甚至是數G的代碼放在一個應用程序中,日後的修改工作會使你變得非常的繁瑣,而且,每次使用帶該功能時如果都重新copy一份這樣的代碼,會大大的浪費代碼的存儲磁盤。如果把不同的功能代碼分別放在數個鏈接庫中共享這部分功能,你無須重新生成或安裝整個程序就可以應用更新,大大方便了程序的編寫。
例:library目錄下有file1、file2、file3和LIB三個目錄,如下:
library--file1--file1.c hello.h hello.c
--file2--file2.c hi.c hi.h
--file3 file3.h file3.cpp
--LIB
在當前目錄下生成庫調用
[root@centos-64-min file1]# cat file1.h
void play1();
[root@centos-64-min file1]# cat file1.c
#include<stdio.h>
#include"file1.h"
int main(void)
{
play1();
return 0;
}
[root@centos-64-min file1]# cat play1.c
#include<stdio.h>
void play1(void)
{
printf("hello file1\n");
}
問題一:
[root@centos-64-min file1]# gcc --shared play1.c -o libplay1.so
/usr/bin/ld: /tmp/ccX7Elnx.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/tmp/ccX7Elnx.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
解決方法:
[root@centos-64-min file1]# gcc -fPIC --shared play1.c -o libplay1.so
問題二:
[root@centos-64-min file1]# gcc -o file1 file1.c libplay1.so
[root@centos-64-min file1]# ./file1
./file1: error while loading shared libraries: libplay1.so: cannot open shared object file: No such file or directory
出現這種情況主要是因為執行文件找不到 play1庫,致使鏈接不到,在編譯時指明庫所在的位置就可以了。
解決方法:
[root@centos-64-min file1]# gcc -o file1 file1.c ./libplay1.so
[root@centos-64-min file1]# ./file1
hello file1
[root@centos-64-min file2]# cat file2.c
#include<stdio.h>
#include“hi.h”
int main(void)
{
hi();
return 0;
}
[root@centos-64-min file2]# cat hi.h
#include“hi.c”
void hi();
[root@centos-64-min file2]# cat hi.c
#include<stdio.h>
void hi(void)
{
printf("hi file2\n");
}
運行結果:
[root@centos-64-min file2]# gcc -o file2 file2.c
[root@centos-64-min file2]# ./file2
hi file2
把file1和file2生成的庫存放到LIB中
[root@centos-64-min file2]# cp libfile2.so ../LIB/
[root@centos-64-min file1]# cp libplay1.so ../LIB/
[root@centos-64-min LIB]# ls
libfile2.so libplay1.so
在file3中編寫c++文件調用LIB中庫
[root@centos-64-min file3]# cat file3.cpp
#include<iostream.h>
int main(void)
{
play1();
hi();
return 0;
}
[root@centos-64-min file3]# cat file3.h
#ifdef __cplusplus
extern "C"
{
#endif
void hi();
void play1();
#ifdef __cplusplus
}
#endif
[root@centos-64-min file3]# g++ -o file3 file3.h file3.cpp ../LIB/libfile2.so ../LIB/libplay1.so
[root@centos-64-min file3]# ./file3
hello file1
hi file2
庫有C編譯生成的庫和C++編譯生成的庫,下面解析下C如何調用C++的庫、C++如何調用C的庫。