我是使用 macos 系统操作的,请先阅读 GCC系列: Homebrew安装GCC和binutils 这篇文章。如果你已经安装了 GCC 编译器,可以继续往下看。
GCC 加载链接库会依赖加载顺序,这样会导致无法调用预期的方法。
下面举例说明。
Car 和 Bus 都有 drive
函数,在 main 里面调用谁的 drive
, 取决于链接库的加载顺序。
Car.c
示例代码,如下:
#include<stdio.h>
#include<stdlib.h>
int drive()
{
printf("Car driving...\n");
return 0;
}
void stop()
{
printf("Car stop.\n");
}
Bus.c
示例代码,如下:
#include<stdio.h>
#include<stdlib.h>
int drive()
{
printf("Bus driving...\n");
return 0;
}
void start()
{
printf("Bus start.\n");
}
这里注意: Car 和 Bus 都有 drive 函数。
现在把 Car.c 和 Bus.c 分别编译生成独立的两个静态库(.so)文件,命令如下:
gcc-4.9 -shared -o libBus.so Bus.c
gcc-4.9 -shared -o libCar.so Car.c
编译完成之后,会有对应的 so 库文件生成。
接下来,开始使用这两个库文件。
main.c
示例代码,如下:
#include<stdio.h>
#include<stdlib.h>
//
// 在 gcc 编译器下, 必须声明方法
// 在 clang 编译下, 只是给了警告
//
int drive();
void start();
void stop();
int main()
{
drive();
stop();
start();
return 0;
}
编译 main.c,如下:
gcc-4.9 -o app main.c -L ./ -lCar -lBus
运行可执行文件 app,如下:
./app
Car driving...
Car stop.
Bus start.
我们交换一下链接库顺序再来编译 main.c
,如下重新编译:
gcc-4.9 -o app2 main.c -L ./ -lBus -lCar
再次运行可执行文件 app2,如下:
./app2
Bus driving...
Car stop.
Bus start.
从执行结果中可以看出,编译时链接库顺序不一样,调用的函数(drive
)也不一样。