zoukankan      html  css  js  c++  java
  • C 语言 和 python 调用 .so 文件

    什么是静态库和动态库, 看一篇博客

    http://www.cnblogs.com/skynet/p/3372855.html

    现在,我们首先生成.so文件

    首先, 我们写一个a.c文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
     
    void show() {
        printf("this is a test ");
    }
     
    int add(int a, int b) {
        return a + b;
    }

      

     然后输入命令

    1
    gcc a.c -fPIC -shared -o a.so

       在当前目录下会产生一个a.so文件

     其中 -fPIC是position independent code(位置无关代码)的意思

       -shared是产生一个可以与其他对象连接来形成一个可执行文件的共享对象的一个参数

    首先, python中调用.so库

    1
    2
    3
    4
    5
    6
    7
    from ctypes import cdll
     
    cur = cdll.LoadLibrary('./a.so')
     
    cur.show()
     
    print cur.add(12)

     结果如下

    1
    2
    hello, world!
    3

     

    然后,在C语言中调用.so文件

     首先看一组API

    1
    2
    3
    4
    5
    #include <dlfcn.h>
    void *dlopen(const char *filename, int flag);
    void *dlsym(void *handle, const char *symbol);
    int dlclose(void *handle);
    char *dlerror(void);

     下面, 分别解释这几个函数

    dlopen

    dlopen()函数以指定模式打开指定的动态链接库文件,并返回动态链接库的句柄。参数flag有以下两种常用的值,并且必须指定其一。 RTLD_LAZY:在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址。 RTLD_NOW:与上面不同,他需要在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL.

    dlsym

    dlsym()函数根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的地址。使用这个函数不但可以获取函数地址,也可以获取变量地址。参数的含义如下: handle:由dlopen打开动态链接库后返回的指针; symbol:要求获取的函数或全局变量的名称。

    dlclose

    dlclose()函数用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

    dlerror

    当动态链接库操作函数,如dlopen/dlsym/dlclose//执行失败时,dlerror()函数可以返回最近的出错信息,返回值为NULL时表示操作函数执行成功。

    C语言用户需要包含头文件dlfcn.h才能使用上述API。

    然后, 我们新建一个main.c文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /**
    #include <dlfcn.h>
    void *dlopen(const char *filename, int flag);
    void *dlsym(void *handle, const char *symbol);
    int dlclose(void *handle);
    char *dlerror(void);
    **/
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <dlfcn.h>
     
    int main() {
     
        void *foo = dlopen("./a.so", RTLD_LAZY);
        dlerror();
        void (*fun)() = dlsym(foo, "show");
        int (*fun1)(intint) = dlsym(foo, "add");
        fun();
        printf("%d ", fun1(1, 2));
        dlclose(foo);
     
        return 0;
    }

      

    然后编译命令

    1
    gcc main.c -ldl

      输出结果:

    1
    2
    hello, world!
    3
  • 相关阅读:
    数据库面试题
    数据库面试题
    DevExpress GridView 鼠标悬停颜色追踪(行或单元格)
    DevExpress GridView 鼠标悬停颜色追踪(行或单元格)
    2015最新最全最详细的配置win8.1开启IIS和ASP
    2015最新最全最详细的配置win8.1开启IIS和ASP
    打开IIS管理器命令cmd
    打开IIS管理器命令cmd
    C#在方法或属性中使用sealed时的操作与原理
    C#在方法或属性中使用sealed时的操作与原理
  • 原文地址:https://www.cnblogs.com/jkred369/p/7406084.html
Copyright © 2011-2022 走看看