栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python调用动态链接库详解

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python调用动态链接库详解

python调用动态链接库详解
  • Python 调用动态链接库
    • 环境说明
    • 构建动态链接库
    • 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 ..
make
python动态链接库基础调用

将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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/331093.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号