so文件的编译与使用

  • C使用so文件
    • 方法一
    • 方法二
  • python使用so文件

C使用so文件

共写了两个c文件和两个h文件。

文件一:calculate.c
#include "min.h"
int max(int a,int b){return a>b?a:b;
}
int whoissmall(int a,int b){return min(a,b);
}文件二:calculate.h
int max(int a,int b);
int whoissmall(int a,int b);文件三:min.c
int min(int a,int b){return a<b?a:b;
}文件四:min.h
int min(int a,int b);

方法一

  1. 利用以下命令将两个c文件生成一个so文件,此处生成的so文件为libcalculate.so,(so文件名要求前缀为lib,扩展名为so)
    gcc -shared -fPIC min.c calculate.c -o libcalculate.so。

  2. 接着新建一个main.c,其中用到了so文件中的calculate.c中实现的函数,需要将头文件include进来。

文件名:main.c
#include <stdio.h>
#include <stdlib.h>
#include "calculate.h"
int main() {printf("%d\n", whoissmall(1,2));
}
  1. 用以下命令编译,
gcc main.c -lcalculate -L testso/ -I testso/  -o main
1. -l代表所连接的so文件的名字,因为我这里用的是libcalculate.so,连接的时候需要去掉lib和.so。
2. -L是代表so文件所在的位置
3. -I是代表编译的c文件(这里是main.c)所include的头文件的位置。这里使用的whoissmall函数是calculate.c中实现的,所以include calculate.h。(同样,若想用min.h中的min函数,在main.c中include min.h即可)。扩展:
1. 对于-L,可通过以下命令来添加gcc寻找so文件的位置。
export LIBRARY_PATH=/home/haimiao/testso:$LIBRARY_PATH
这样编译的时候直接写gcc main.c -lcalculate -I testso/  -o main即可。
gcc在寻找so文件时的寻找顺序为-L > /lib和/usr/lib和/usr/local/lib > LIBRARY_PATH。
2. 对于-I ,gcc默认寻找头文件的位置/usr/include和本目录下,因而若希望找到头文件在别的目录下,需要加-I。
  1. 直接运行main即可。

方法二

  1. 使用方法一的so文件,改写main.c。
main2.c#include <stdio.h>
#include <dlfcn.h>
int main(){void* handle;int(*func) (int, int);char* error;handle = dlopen("libcalculate.so", RTLD_LAZY);if (!handle) {printf("%s\n", dlerror());return -1;}func = dlsym(handle, "whoissmall");if ((error = dlerror()) != NULL) {printf("%s\n", error);return -1;}printf("%d\n,", func(1, 2));return 0;
}

以下介绍所用到的函数:
包含头文件:
#include <dlfcn.h>
函数定义:
void * dlopen( const char * pathname, int mode );
函数描述:
在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。
mode:分为这两种
RTLD_LAZY 暂缓决定,等有需要时再解出符号
RTLD_NOW 立即决定,返回前解除所有未决定的符号。
RTLD_LOCAL
RTLD_GLOBAL 允许导出符号
RTLD_GROUP
RTLD_WORLD
返回值:
打开错误返回NULL
成功,返回库引用

void* dlsym(void* handle,const char* symbol)
该函数在<dlfcn.h>文件中。
handle是由dlopen打开动态链接库后返回的指针,symbol就是要求获取的函数的名称,函数返回值是void*,指向函数的地址,供调用使用

dlerror()
包含头文件:
#include <dlfcn.h>
函数原型:
const char *dlerror(void);
函数描述:
当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

dlclose()
包含头文件:
#include <dlfcn.h>
函数原型为:
int dlclose (void *handle);
函数描述:
dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

  1. 编译时需要加上-ldl选项。
gcc main2.c -ldl

若执行时报以下错误
说明so文件找不到,需要设置一下LD_LIBRARY_PATH(为什么方法一时用LD_LIBRARY_PATH不行,只能用LIBRARY_PATH),如下

export LD_LIBRARY_PATH=/home/haimiao/testso:$LD_LIBRARY_PATH
其中冒号前是so文件所在位置,冒号是路径的分隔符。

使用这种方法不需要include头文件。

python使用so文件

这里使用的python版本为2.7.12

  1. 使用的so文件同样如上。改写main.py
from ctypes import cdll
cur = cdll.LoadLibrary('./libcalculate.so')
print cur.whoissmall(1,2)

直接执行即可。

so文件的编译与使用相关推荐

  1. 九、将cs文件快速的转换成可执行文件和响应文件(配置编译开关的文件)

    1.将包含多个类型的源代码文件转换为可以部署的文件.有如下Program.cs的文件,代码如下: public sealed class Program{public static void Main ...

  2. python文件的编译

    背景知识 pyc文件: .pyc 是一种二进制文件,是由 .py 文件经过编译后,生成一种byte code文件. .py 文件变成 .pyc 文件后,加载的速度有所提高,而且 .pyc 是一种跨平台 ...

  3. so文件反编译_安卓攻防so模块自动化修复实战

    前言 Android加固方案经过这么长时间的发展,从开始的整体dex加密压缩方案逐步开始往native层发展,市面上知名的几款商业级加固方案中很容易发现这种方案的身影.这样看来,在今后相当长的一段时间 ...

  4. pyc文件反编译为py文件

    近期时不时需要把工程里的 pyc 文件反编译出来,查看接口函数的逻辑.此前有师兄安利了uncompyle6工具,我使用了几次,发现反编译出来的代码逻辑很清晰,此处我也不能打包票 uncompyle6 ...

  5. 【MyBatis使用】 mapper文件未编译 + statementType使用 + 返回结果字段顺序不一致 + 获取自增ID + 一个update标签批量更新记录

    1. mapper 文件未编译 如果mapper文件未编译,会报绑定异常. <build><resources><resource><directory> ...

  6. tomcat下只有.class文件 没有java文件_解决tomcat发布工程后,WEB-INF/classes下文件不编译的问题...

    今天部署项目到tomcat,发布完后,启动tomcat,报class not found: 临时找了个解决方案,由于项目是copy过来的,于是就将原来项目的classes下面编译好的class文件也一 ...

  7. 小白也能看懂——使用dev-c++建立工程(多个文件一同编译连接)并运行

    关于dev-c++的下载安装不多赘述. 一.创建项目,这里笔者创建的是C++项目,若想创建C项目,改一下选择即可. 二.把项目保存在文件里,最好新建一个同名 的文件夹保存,方便使用. 三.接下来自动弹 ...

  8. 【错误解决】[Maven] cannot be opened because it does not exist错误[文件无法编译到target目录下的解决方法]...

    转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自[大学之旅_谙忆的博客] 使用IDEA搭建的Maven项目,在写SpringEL和资源调用时出现了如下错误: ...

  9. C和指针之预处理器之普通c/c++文件的编译过程

    1.简单总结c/c++文件的编译3个过程 1).预处理器进行预编译   比如我们测试这段代码 #include <stdio.h>int main() {printf("hwll ...

  10. 请教大家:如何把.DCU文件反编译回源代码?谢谢。

    请教大家:如何把.DCU文件反编译回源代码?谢谢. Delphi / Windows SDK/API http://www.delphi2007.net/DelphiAPI/html/delphi_2 ...

最新文章

  1. 小程序如何写tab选项卡
  2. java下载文件跳转页面_java servlet笔记:设置编码集、文件下载和两种服务器跳转-java下载文件...
  3. 【转】如何修改Chrome缓存目录的地址
  4. bootstrap内容部分API解读(1)
  5. Pygame 整活五子棋
  6. java学习(97):中断线程的另一种处理
  7. 一个简单的Makefile模板
  8. 关于网上商城开发的随笔记录2
  9. 消色差、半复消色差、复消色差的区别
  10. python分组求和_Python–多个键分组求和
  11. Git本地仓库的文件夹不显示红色感叹号、绿色对号等图标
  12. 【AAAI 2021】全部接受论文列表(四)
  13. Linux wait和waitpid和kill
  14. 手机拍证件照有什么诀窍
  15. Java程序监控工具
  16. 10 个可以副业赚钱的网站,总有一个适合你
  17. 关于GLSL的gl_FragCoord、gl_FragDepth以及深度计算
  18. Qiyuan-python接小球游戏
  19. Visio画图(直角坐标系和relu函数)
  20. UGUI中随意调整Text中的字体间距

热门文章

  1. FFmpeg 安装与使用
  2. 宏定义(无参,有参,宏函数)(详细介绍)
  3. python 维吉尼亚密码加密和解密
  4. Linux内核下载(包括历史版本)
  5. 万能数据库查询分析器使用技巧之(十五)
  6. nodejs uuid 生成
  7. android ellipsize的使用
  8. USB 协议整理 九:USB 协议调试工程说明
  9. 大系统观:1.4时间之矢
  10. Google Earth Engine(GEE)填补缺失影像