当前位置:   article > 正文

Python调用C函数并封装成类_python调用c函数库生成类实体

python调用c函数库生成类实体

首先环境搭建:

Windows10+python3.6.4+MinGW

这里MinGW我使用的是devc++中的MinGW;

MinGW使用的好处:

习惯在linux中写c程序后对于使用Windows的VS这个IDE怎么用怎么觉得傻逼。使用strcpy这个函数会给我报不安全,然后就得去更改项目属性上的各个参数。除此之外,VS不同版本编译出来的DLL似乎还不能相互识别。怎么用怎么不舒服。

MinGW中除了gcc和g++的编译器外,也有make。只是它的名字是一个有前缀的make。如果需要使用,直接将其更改为make即可。然后将其目录添加至环境变量。打开CMD输入make即可。(原理:操作系统在输入命令后会去找相对应的程序。其寻找路径就是在系统的环境变量里面找。找到后调用其exe文件)

首先是.c文件这里写一个add函数返回int的值

  1. #include"stdio.h"
  2. int add(num1,num2){
  3. return num1+num2;
  4. }

然后写makefile将其编译为动态链接库

  1. adder.so:add.c
  2. gcc -shared -I D:\work_tools\devC++\Dev-Cpp\MinGW64\x86_64-w64-mingw32\include -Wl,-soname,adder -o adder.so -fPIC add.c

然后利用Python3的ctypes库将其方法调用试一下。利用jupyter notebook测试一下是否可以使用ctypes这个库。或者直接在cmd里进入python3然后import ctypes这个库,看是否可以使用。

  1. from ctypes import *
  2. #load the shared object file
  3. adder = CDLL('./adder.so')
  4. #Find sum of integers
  5. res_int = adder.add(4,5)
  6. print ("Sum of 4 and 5 = " + str(res_int))

运行结果

Sum of 4 and 5 = 9

嗯,完美。

好了,接下来封装成类以供别人使用。

使用jupyter的文本编辑器产生的Untitled的文件确实不适合使用,所以个人使用的是NotePad++

它可以更改主题可以使用各种插件。是一个非常强大的文本编辑器。

在当前目录下创建addr.py

代码如下

  1. from ctypes import *
  2. class addNum():
  3. def __init__(self,num1,num2):
  4. self.num1=num1
  5. self.num2=num2
  6. def addr(self):
  7. adder = CDLL('./adder.so')
  8. #Find sum of integers
  9. print("sun is :"+str(adder.add(4,5)))
  10. if __name__=="__main__":
  11. a=addNum(2,4)
  12. a.addr()

进cmd里进入到当前目录

当前目录下的文件应该如下

2020/10/16  02:16    <DIR>          .
2020/10/16  02:16    <DIR>          ..
2020/10/16  02:08    <DIR>          .ipynb_checkpoints
2020/10/16  01:02                61 add.c
2020/10/16  01:03               688 add.o
2020/10/16  01:17           111,335 adder.so
2020/10/16  02:26               274 addr.py
2020/10/16  01:20               137 makefile
2020/10/16  02:12             1,032 Untitled.ipynb

然后运行命令

python3 addr.py

输出结果如下

sun is :9

然后去掉里面的main函数就可以移植。

移植所需要使用的文件只有addr.so add.c 以及addr.py

ok后面就可以封装属于自己的python3底层库了。

其次:避坑指南1:

c函数有指针类型返回值

在64位机器上指针为64位,但实际上ctypes调用的链接库,将会将其默认返回值改为了int。

此时指针类型返回后就会出问题。

解决办法。更改链接库中函数返回值类型。

例:

c的链接库中有 void* a()函数,打包成的动态链接库为test.so

  1. nowSo=CDLL("./test.so")
  2. nowSo.a.restype=POINTER(None)

这样再在python的函数中调用后便能返回指针类型

nowP=(c_void_p)a()

最后添加一个官方文档连接:

https://docs.python.org/zh-cn/3.7/library/ctypes.html

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/392661
推荐阅读
相关标签
  

闽ICP备14008679号