Linux下生成动态链接库、调用动态链接库生成可执行文件

一、Linux下生成动态链接库

//func.c
# include 

int add(int a , int b)
{
	return a+b;
}

void func()
{
    printf("hello world......\n");
}

命令行:gcc -shared -fpic -lm -ldl -o libfunc.so func.c
可生成动态链接库.so文件

二、Linux下调用动态链接库生成可执行文件

//test.cpp
# include 
# include 
# include 
# include 

using namespace std;

int main()
{
    int result = 0;

    void *handle = dlopen("./libfunc.so" , RTLD_LAZY);//相对地址和绝对地址都可以

    if(!handle)
    {
        cout<<"open lib error\n";
        cout<<dlerror()<<endl;
        return -1;
    }

    typedef int(*add_t)(int a, int b);//typedef函数指针
    add_t add = (add_t)dlsym(handle, "add");
    if(!add)
    {
        cout<<dlerror()<<endl;
        dlclose(handle);
        return -1;
    }
        
    int a, b;
    cout<<"请输入要相加的两个数:";
    cin>>a>>b;
    result = add(a, b);
	cout<<a<<"+"<<b<<"="<<result<<endl;

    typedef void(*f_t)();
    f_t f = (f_t)dlsym(handle , "func");
    if(!f)
    {
        cout<<dlerror()<<endl;
        dlclose(handle);
        return -1;
    }
    f();

    dlclose(handle);

	return 0;
}

命令行:g++ test.cpp -ldl -o test
可实现test.c生成可执行文件test后,在运行的时候自动加载动态链接库里的函数

三、调用动态链接库的函数说明

函数原型: void *dlopen(const char *libname,int flag);
功能描述: dlopen必须在dlerror,dlsym和dlclose之前调用,表示要将库装载到内存,准备使用。如果要装载的库依赖于其它库,必须首先装载依赖库。如果dlopen操作失败,返回NULL值;如果库已经被装载过,则dlopen会返回同样的句柄。
参数中的libname一般是库的全路径,这样dlopen会直接装载该文件;也可以用相对地址。

flag参数表示处理未定义函数的方式,可以使用RTLD_LAZY或RTLD_NOW。RTLD_LAZY表示暂时不去处理未定义函数,先把库装载到内存,等用到没定义的函数再说;RTLD_NOW表示马上检查是否存在未定义的函数,若存在,则dlopen以失败告终。

函数原型: char *dlerror(void);
功能描述: dlerror可以获得最近一次dlopen,dlsym或dlclose操作的错误信息,返回NULL表示无错误。dlerror在返回错误信息的同时,也会清除错误信息。

函数原型: void *dlsym(void *handle,const char *symbol);
功能描述: 在dlopen之后,库被装载到内存。dlsym可以获得指定函数(symbol)在内存中的位置(指针)。如果找不到指定函数,则dlsym会返回NULL值。但判断函数是否存在最好的方法是使用dlerror函数,

函数原型: int dlclose(void *);
功能描述: 将已经装载的库句柄减一,如果句柄减至零,则该库会被卸载。如果存在析构函数,则在dlclose之后,析构函数会被调用。

四、注意:
1、要生成动态链接库的文件必须是C语言写的,(C++会报错,但是一大佬解析完符号表就可以了)。而调用动态链接库的文件可以用C++。
2、计算机系统基础课本上有 gcc -o myproc main.c ./mylib.so可以生成部分链接的可执行文件,在加载时,由加载器将控制权转到指定的加载器,然后进行重定位和加载共享库,之后动态链接器又把控制权转移到成语myproc。但一般还是使用上面的命令来调用动态链接库比较好。

你可能感兴趣的:(课程设计/实践)