- Python 调用动态链接库
- 环境说明
- 构建动态链接库
- python动态链接库基础调用
- python动态链接库结构体调用
- python动态链接库回调函数
- linux操作系统中动态链接库为so文件。
- python调用so文件使用动态方式加载,python中使用ctypes库
- ctypes是Python调用c的动态链接库的一个内置模块。
- 操作系统:linux
- python: python3
- 项目结构
├── CMakeLists.txt # cmake构建配置文件 ├── hello.cc # 动态链接库源文件 └── hello.h # 动态链接库头文件
- CMakeLists.txt
cmake_minimum_required(VERSION 3.1) # 设置cmake最小版本
project(hello) # 设置项目名称
set(src_h hello.h) # 设置头文件
set(src_c hello.c) # 设置源文件
add_library( hello SHARED ${src_h} ${src_c}) # 生成libhello.so库文件。
- hello.h
#ifdef __cplusplus
extern "C"{
#endif
#ifndef _HELLO_H_
#define _HELLO_H_
// -------------- so基础调用 -------------
void say_hello(); // 基础调用,无参数调用
void say_hello2(int iNum); // 传递int类型参数
void say_hello3(const char *str); // 传递char * 字符串
int say_hello4(int iNum1,int Num2); // 传递两个参数,并且带返回值。
// -------------- so结构体调用 -------------
struct POINT{
int x;
int y;
};
struct POINT get_mouse_position(); // 返回结构体
struct POINT *get_position(); // 返回结构体指针
void release_point(struct POINT * ptrData); // 将结构指针作为参数
// -------------- so 回调函数 -------------
typedef void (callback)();
typedef int (callback2)(int);
void send_message(int a, callback funcPtr); // 无参数的回调函数
int send_message2(int a, callback2 funcPtr); // 带参数,带返回值的回调函数
#ifdef __cplusplus
}
#endif
#endif
- hello.c
#include#include #include "hello.h" void say_hello(){ printf("hellorn"); } void say_hello2(int iNum){ printf("hello2 num:%drn",iNum); } void say_hello3(const char *str){ printf("hello3 str:%srn",str); } int say_hello4(int iNum1,int iNum2){ int res = iNum1 + iNum2; printf("hello4 res:%drn",res); return res; } struct POINT get_mouse_position(){ struct POINT temp; temp.x = 12; temp.y = 13; return temp; } struct POINT *get_position(){ struct POINT *temp =NULL; temp = (struct POINT *)malloc(sizeof(struct POINT)); temp->x = 10; temp->y = 20; return temp; } void release_point(struct POINT * ptrData){ if(NULL != ptrData){ free(ptrData); ptrData = NULL; } } void send_message(int a, callback funcPtr){ printf("send_message a:%drn",a); if(funcPtr != NULL) funcPtr(); } int send_message2(int a, callback2 funcPtr){ printf("send_message2 a:%drn",a); if(funcPtr != NULL){ int res= funcPtr(6); printf("回调函数的执行结果为:%drn",res); } return 5; }
- 构建步骤,如果生成libhello.so文件那么就构建成功了
mkdir build cd build cmake .. makepython动态链接库基础调用
将so文件拷贝到py文件的同级目录
运行命令:
python3 main.py
目录结构如下:
├── libhello.so └── main.py
main.py
import ctypes
from ctypes import *
solib = ctypes.CDLL('./libhello.so')
func_say_hello = solib.say_hello
func_say_hello()
print("func_say_hello 执行完毕!")
print("============================")
func_say_hello2 = solib.say_hello2
func_say_hello2(2)
print("func_say_hello2 执行完毕!")
print("============================")
func_say_hello3 = solib.say_hello3
str = "I love you"
func_say_hello3(str.encode("UTF-8"))
print("func_say_hello3 执行完毕!")
print("============================")
func_say_hello4 = solib.say_hello4
res = func_say_hello4(5,6)
print("func_say_hello3 执行完毕!结果为:",res)
print("============================")
执行结果如下:
hello func_say_hello 执行完毕! ============================ hello2 2 func_say_hello2 执行完毕! ============================ hello3 I love you func_say_hello3 执行完毕! ============================ hello4 11 func_say_hello3 执行完毕!结果为: 11 ============================python动态链接库结构体调用
main.py
import ctypes
from ctypes import *
class PyPointStruct(Structure):
_fields_ = [
("x", c_int),
("y", c_int),
]
solib = ctypes.CDLL('./libhello.so')
func_get_mouse_position = solib.get_mouse_position
func_get_mouse_position.restype = PyPointStruct # 设置函数返回结果的类型为结构体
resp = func_get_mouse_position()
print("res2:",resp.x)
print("res2:",resp.y)
print("============================")
func_get_position = solib.get_position
func_get_position.restype = POINTER(PyPointStruct) # 设置函数返回结果的类型为结构体指针
resb = func_get_position()
print("res3:",resb.contents.x)
print("res3:",resb.contents.y)
print("============================")
执行结果如下:
res2: 12 res2: 13 ============================ res3: 10 res3: 20 ============================python动态链接库回调函数
main.py
import ctypes
from ctypes import *
solib = ctypes.CDLL('./libhello.so') # 加载动态链接库
def cb_sayhello(): # 无参数的回调函数
print("python hello")
def cb_sayhello2(res): # 带参数有返回值的回调函数。
print("python hello2,res:",res)
return 1024
solib = ctypes.CDLL('./libhello.so')
func_send_message = solib.send_message
# CFUNCTYPE定义方法的签名,第一参数表示方法的返回类型,后面开始编译参数的类型
funcStruct = CFUNCTYPE(None)
solib.send_message(10,funcStruct(cb_sayhello))
print("============================")
send_message2 = solib.send_message2
# CFUNCTYPE定义方法的签名,第一参数表示方法的返回值,后面开始编译参数的类型
funcStruct2 = CFUNCTYPE(c_int,c_int)
send_message2(10,funcStruct2(cb_sayhello2))
print("============================")
执行结果:
send_message a:10 python hello ============================ send_message2 a:10 python hello2,res: 6 回调函数的执行结果为:1024 ============================
代码下载地址
https://download.csdn.net/download/arv002/33253778



