python 调用dll 动态链接库 结构体参数及回调函数等示例
结构体示例:
这里是 C 代码的部分,主要是结构体的声明和回调函数定义。
// 新版本定义
typedef enum {
DevCard,
DevLocator,
DevReader
} DevType;
typedef enum {
MsgLocate, // 定位信号
MsgCut, // 剪断信号
MsgHeartBeat, // 心跳信号
MsgCall, // 呼叫信号
MsgShake, // 震动信号
MsgLeave, // 离开信号
MsgOffAlarm, // 报警灯关闭信号
MsgCheckPower, // 电量检测信号
MsgHeartRate, // 心率信号
MsgExtra, // 补发信号
MsgNoPower, // 没电信号
MsgReset, // 重置信号
MsgBoundary, // 跨界信号
// 此消息会跟随着MsgLocate消息出现
MsgPower,
// 当checkOffline设置为1时有效。如果在offlineTime时间内没有收到此设备的信号,则发出离线信号
MsgOffline,
MsgLast
} MsgType;
// 由于消息类型的不同,不是所有的值都有意义
typedef struct {
MsgType type;
DevType device; // 硬件类型
int32_t cardID; // 标签/腕带ID,当DevType为DevCard时有意义
int32_t readerID; // 阅读器ID,总是有意义
int32_t locatorID; // 大于0时有意义,表示定位器ID
int32_t readerRSSI; // 阅读器信号强度,由于硬件版本的差异,此值要么全有意义,要么全没意义(总是0)
int32_t locatorRssiX; // 当MsgType为[MsgLocate, MsgExtra]时,此值有意义,表示定位器的信号强度
int32_t locatorRssiY; // 定位器的信号强度
uint8_t isCut; // 如果此值为1,表示硬件被破坏。因为有专门的MsgCut消息,可以忽视此值
uint8_t isShake; // 如果此值为1,表示硬件处于震动状态。仅当MsgType为MsgShake是有意义,1表示震动,0表示静止
uint8_t isLowpower; // 硬件是否低电。硬件为标签时有意义,因为有追加的MsgPower消息,可以在MsgType为MsgPower时使用此值
int32_t heartRate; // 心率,当MsgType为[MsgHeartBeat, MsgHeartRate]之一时有意义
int32_t power; // 电量,当MsgType为[MsgHeartBeat, MsgReset, MsgCheckPower]之一时有意义
int64_t time; // 消息时间戳
int version; // 硬件版本号,DevType为DevCard时有意义
} DevMsg;
typedef void(*MsgCallback)(DevMsg msg, void *ctx);
extern "C" {
DEVSDK_API int ccrfidDevSdkStartWork(MsgCallback fun, void *ctx);
}
# coding=UTF-8
from ctypes import *
import time
import _ctypes
# 定义回调函数参数的结构体
class DevMsg(Structure):
_fields_ = [("type", c_long),
("device", c_long),
("cardID", c_long),
("readerID", c_long),
("locatorID", c_long),
("readerRSSI", c_long),
("locatorRssiX", c_long),
("locatorRssiY", c_long),
("isCut", c_char),
("isShake", c_char),
("isLowpower", c_char),
("heartRate", c_long),
("power", c_long),
("time", c_longlong),
("version", c_long)]
注意一下 _fields_的内容:这里就是对 C 数据类型的转换。左边是 C 的结构成员名称,右边则是在 python 中声明一下各个成员的类型。其他的一些类型请参见官方文档。
此外还需要注意一下类似于 c_int, c_void_p 等等的定义是在 ctypes 中的,如果是用import ctypes 的方式包含 ctypes 模块,则应该写成 ctypes.c_long, ctypes.c_longlong,ctypes.c_char。
第三个要注意的是:这个类必须定义为 ctypes.Structure 的子类,否则在进行后续的函数传递时,ctypes 由于不知道如何进行数据类型的对应,会抛出异常
回调函数示例:
# 定义功能类与方法
class DemoDll:
def __init__(self):
self.dll = cdll.LoadLibrary('ccrfidDevSDK.dll')
return
def ccrfidDevSdkStartWork(self, callback, p):
return self.dll.ccrfidDevSdkStartWork(callback, p)
# ctypes通过 CFUNCTYPE 支持回调函数,定义返回值与参数,第一个参数表示返回值,void为None
CALLBACK = CFUNCTYPE(None, POINTER(DevMsg))
最后的 CALLBACK通过 ctypes 定义了一个回调函数类型,这个在后面的调用中需要使用
在 CFUNCTYPE 后面的第一个参数为 None,这表示回调函数的返回值类型为 void
完整功能示例:
# coding=UTF-8
from ctypes import *
import time
import _ctypes
# 定义回调函数参数的结构体
class DevMsg(Structure):
_fields_ = [("type", c_long),
("device", c_long),
("cardID", c_long),
("readerID", c_long),
("locatorID", c_long),
("readerRSSI", c_long),
("locatorRssiX", c_long),
("locatorRssiY", c_long),
("isCut", c_char),
("isShake", c_char),
("isLowpower", c_char),
("heartRate", c_long),
("power", c_long),
("time", c_longlong),
("version", c_long)]
# 定义功能类与方法
class DemoDll:
def __init__(self):
self.dll = cdll.LoadLibrary('ccrfidDevSDK.dll')
return
def ccrfidDevSdkStartWork(self, callback, p):
return self.dll.ccrfidDevSdkStartWork(callback, p)
# ctypes通过 CFUNCTYPE 支持回调函数,定义返回值与参数,第一个参数表示返回值,void为None,第二参数为回调函数的参数为结构体指针
CALLBACK = CFUNCTYPE(None, POINTER(DevMsg))
# 回调函数距离功能实现
def _callback(para):
# print(dir(para))
obj = para.__getitem__(0)
print(obj.type, obj.cardID, obj.readerID, obj.locatorID, obj.heartRate, obj.power, obj.time, obj.version)
# 定义回调函数
callBackFunc = CALLBACK(_callback)
# 实例化功能类
dll = DemoDll()
# 定义一个空的指针
null_ptr = POINTER(c_int)()
# 具体功能调用
c = dll.ccrfidDevSdkStartWork(callBackFunc, null_ptr)
print(c)
time.sleep(100000)
运行结果

python 调用dll 动态链接库 结构体参数及回调函数等示例的更多相关文章
- Python调用DLL动态链接库——ctypes使用
最近要使用python调用C++编译生成的DLL动态链接库,因此学习了一下ctypes库的基本使用. ctypes是一个用于Python的外部函数库,它提供C兼容的数据类型,并允许在DLL或共享库中调 ...
- python调用c/c++时传递结构体参数
背景:使用python调用linux的动态库SO文件,并调用里边的c函数,向里边传递结构体参数.直接上代码 //test1.c # include <stdio.h> # include ...
- 绝对好文C#调用C++DLL传递结构体数组的终极解决方案
C#调用C++DLL传递结构体数组的终极解决方案 时间 2013-09-17 18:40:56 CSDN博客相似文章 (0) 原文 http://blog.csdn.net/xxdddail/art ...
- C#中调用Dll动态链接库
C#中调用Dll动态链接库 起始 受限于语言的不同,我们有的时候可能会用别人提供的函数及方法 或者其他的什么原因.反正就是要调!!! 恰巧别人所使用的的语言跟自己又不是一样的 这个时候想要调用别人的函 ...
- x264中重要结构体参数解释,参数设置,函数说明 <转>
x264中重要结构体参数解释http://www.usr.cc/thread-51995-1-3.htmlx264参数设置http://www.usr.cc/thread-51996-1-3.html ...
- Qt--信号槽传递自定义结构体参数
自定义结构体参数的信号槽连接 (1) 对于自定义的结构体参数,信号槽无法识别参数,导致信号槽连接不起作用.所以需要注册结构体参数.在结构体中声明结束的地方加上结构体注册. struct DealDet ...
- python调用dll详解
参考链接https://www.cnblogs.com/TQCAI/p/8881530.html https://www.jb51.net/article/52513.htm https://www. ...
- Go结构体实现类似成员函数机制
Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...
- (60) 结构体指针、结构体变量嵌套、结构体指针嵌套、函数指针、数组指针、指针数组、typedef 综合运用
#include<stdio.h> #include<iostream> #include<malloc.h> /* author : 吴永聪 program: 结 ...
随机推荐
- (51)LINUX应用编程和网络编程之六Linux高级IO
3.6.1.非阻塞IO 3.6.1.1.阻塞与非阻塞 阻塞:阻塞具有很多优势(是linux系统的默认设置),单路IO的时候使用阻塞式IO没有降低CPU的性能 补充:阻塞/非阻塞, 它们是程序在等待消息 ...
- Linux vi/vim and linux yum 命令
Linux vi/vim 所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主 ...
- Codechef TRIPS Children Trips (分块、倍增)
题目链接: https://www.codechef.com/problems/TRIPS 感觉CC有点毒瘤啊.. 题解: 首先有一个性质可能是因为太傻所以网上没人解释,然而我看了半天: 就是正序和倒 ...
- Spring Cloud云架构 - commonservice-sso服务搭建(一)
前面几篇我们已经介绍了Spring Cloud和oauth2的知识点,今天我们要利用Spring Cloud和oauth2进行commonservice-sso服务搭建,本节我们只是搭建commons ...
- android字符串工具类
package com.ctbri.weather.utils.calendar; /** * Created by IntelliJ IDEA. * User: zhouxin@easier.cn ...
- HDU 6625 (01字典树)
题意:给定两个长为n的数组a和b:重新排列a和b,生成数组c,c[i]=a[i] xor b[i]:输出字典序最小的c数组. 分析:将a中的数插入一颗01字典树a中:将b中的数插入一颗01字典树b中: ...
- legend3---OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
legend3---OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054 一.总结 一句话总结: 解决方法:多试几次,实在不行就手动下载 1.homeste ...
- iOS SDK开发之 .a静态库
查看.framework静态库的生成及使用单击此处 注:这篇教程将只使用一小部分Objective-C代码,本文主要讲解从开始到应用的详细步骤.环境:xcode 9.2下面我们开始操作: 第一步:创建 ...
- C#爬虫之Senlium
在爬虫过程中,有的网页是动态更新的,有的数据会在页面加载时通过js加载或者用ajax加载,这时候如果只用普通的Request和Response获取的HTML页面将会不完整.所以这时候可以采用Senli ...
- 中国MOOC_零基础学Java语言_第1周 计算_第1周编程题_1温度转换
第1周编程题 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将 ...