链接库

2019-07-10  本文已影响0人  zoant

命名

"lib" + soname + ".so" + 主版本号 + 发行版本号(可选)
注意:有些不以lib开头

简例

/*phello.h*/
extern "C" void ph();

 /*phello.cpp*/
#include <stdio.h>
#include "phello.h"

void ph()
{
    printf("hello");
}

gcc -shared -fPIC phello.cpp -o libph.so

-shared:这是个动态库
-fPIC:位置无关代码(Position Independent Code)

静态加载

/*main.cpp*/
#include <stdio.h>
#include <phello.h>

int main(int argc, char** argv)
{
    ph();
    return 0;
}

gcc main.cpp -o main -L./ -lph -I./

-L:动态库目录
-l:动态库
-I:头文件目录

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

环境变量LD_LIBRARY_PATH,从当前目录查找so

./main

执行

动态加载

/*main.cpp*/
#include <stdio.h>
#include <dlfcn.h>

#define DLL_FILE_NAME "./libph.so"

int main(int argc, char** argv)
{
    void *handle;
    void (*func)();

    handle = dlopen(DLL_FILE_NAME, RTLD_NOW);
    if (handle == NULL)
    {
        printf("Failed to open libaray %s error:%s\n", DLL_FILE_NAME, dlerror());
        return -1;
    }

    func = (void (*)())dlsym(handle, "ph");
    if (handle == NULL)
    {
        printf("error:%s\n", dlerror());
        return -1;
    }
    func();
    dlclose(handle);
    return 0;
}

gcc main.cpp -o main -lph

编译

./main

执行


函数详解

dlopen
打开方式

dlclose
so打开会有计时器,dlclose相当减一,当为0时自动从内存中卸载

extern “C”
可以修饰函数和变量
表示用c语言风格来编译
这里so的函数必须使用extern “C”修饰,否则dlsym会报错
以为c++为了使用多态,会把函数名和参数联合起来生成一个中间的函数名称

构造和析构
void attribute(constructor) x_init(void)
void attribute(destructor) x_fini(void)
分别在dlopen和dlclose前后被调用
函数名可以随意起

相关命令

ldd ./main

可以查看./main依赖的所有so

上一篇 下一篇

猜你喜欢

热点阅读