GCC: 共享库

基本概念

共享库: 在程序执行期间需要调用到共享库的时候才加载到内存里面,可以被多个程序共享使用.

在 MacOS 上面创建和使用共享库要比在 Linux 上面简单.
在 Linux 上面还会牵扯到共享库路径问题, 在 Mac 上面就没有这样的问题.

在 MacOS 上面使用的 GCC 其本质是 LLVM. 你可以在命令行:

gcc -v

可以看到对应的输出结果:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.37)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

创建共享库步骤

[1].写源文件.这里以 C文件为基础.
[2].将源文件生成目标文件.
[3].创建共享库.
[4].写头文件, 供调用方使用.

下面结合实例来分享一下如何在 Mac 上面创建共享库.

写源文件

目录结构:
1

对应的完整代码可以看文末的附录.

生成目标文件

执行如下命令:

gcc -Wall -c -fPIC libs/eat.c libs/play.c libs/sleep.c libs/person.c

注意: -fPIC 选项一定要加.

PIC(position independent code), 产生位置无关码

生成共享库

这里把共享库暂且称之为 libperson.so.

执行下面命令创建:

gcc -shared -fPIC eat.o play.o sleep.o person.o -o libperson.so

写头文件

这里头文件主要是 person.h

#ifndef _PERSON_H
#define _PERSON_H
extern void init(int pUid);
extern void eat();
extern void play();
extern void sleep();
#endif

使用共享库

main.c 是使用方, 编译链接即可.

gcc main.c -L. -lperson -Ilibs -o main

生成可执行文件 main, 执行结果:

From sharedlib.uid: 101 eating
From sharedlib.uid: 101 playing
From sharedlib.uid: 101 has sleep

注意:
-L 选项, 告诉编译器去哪里找库文件, 这里的 _L. 表示在当前目录.

-lperson, 表示 libperson.so 库.

-Ilibs 告诉编译器头文件所在的目录.

附录

示例完整代码

main.c

#include <stdio.h>
#include "person.h"
int main() {
init(101);
eat();
play();
sleep();
}

person.h

#ifndef _PERSON_H
#define _PERSON_H
extern void init(int pUid);
extern void eat();
extern void play();
extern void sleep();
#endif

person.c

int uid;
void init(int pUid) {
uid = pUid;
}

eat.c

#include <stdio.h>
extern int uid;
void eat() {
printf("From sharedlib.uid: %i eating\n", uid);
}

play.c

#include <stdio.h>
extern int uid;
void play() {
printf("From sharedlib.uid: %i playing\n", uid);
}

sleep.c

#include <stdio.h>
extern int uid;
void sleep() {
printf("From sharedlib.uid: %i has sleep\n", uid);
}

GCC 系列博文

坚持原创技术分享,您的支持将鼓励我继续创作!