其实是python后台程序常用方法:

C开发完成底层的功能,python直接把C当做python模块进行调用。

需要做两个工作:

python能调用C语言的函数;

python通过调用C函数,并注册python的回调函数,C代码通过python回调函数告诉Python当前实时进度和状态;

1,python如何调用C语言

主要就是应用ctypes这个模块,too simple too naive。

python代码是这样滴:

fromctypesimport*

dynamicLibString = './libcheckVideoFile.so'

mylib = cdll.LoadLibrary(dynamicLibString)

ulHandle = mylib.VideoAnalyzeInit(videoFilename)

ifulHandle ==0:

print'VideoAnalyzeInit error.'

print''

mylib.EnableBlackDetected(ulHandle)

mylib.EnablePureColorDetected(ulHandle)

mylib.EnableFrozenDetected(ulHandle)

mylib.EnableMuteVoiceDetected(ulHandle)

C代码是这样滴:

unsignedlongVideoAnalyzeInit(char* szFilename)

{

VideoAnalyzeManage* pManager = newVideoAnalyzeManage(szFilename);

if(pManager)

{

intiRet = pManager->Init();

if(iRet != 0)

{

deletepManager;

return0;

}

}

return(unsignedlong)pManager;

}

voidEnableBlackDetected(unsignedlongulHandle)

{

VideoAnalyzeManage* pManager = (VideoAnalyzeManage*)ulHandle;

if(pManager)

{

pManager->EnableBlackDetected();

}

}

就像C语言编译出来的.so库只是python的一个模块,直接调用就可以了。

2,python注册C语言的回调函数

其实也不难,python的函数本身也是python的对象,实现也就简单了:

python的回调函数:

defOnPyVideoAnalyzeResultCallback(ulStartTS, ulEndTS, ulDetectedType, ulParam):

fStartTS = ulStartTS/1000.0

fEndTS   = ulEndTS/1000.0

outputString = ''

ifulDetectedType == ALL_BLACK_DETECTED :

outputString = videoFilename + ': All black color detected: start('+ str(fStartTS) +') end('+ str(fEndTS) +')'

elifulDetectedType == SIMPLE_COLOR_DETECTED :

outputString = videoFilename + ': All pure color detected: start('+ str(fStartTS) +') end('+ str(fEndTS) +')'

elifulDetectedType == FROZEN_VIDEO_DETECTED :

outputString = videoFilename + ': Frozen image detected: start('+ str(fStartTS) +') end('+ str(fEndTS) +')'

elifulDetectedType == AUDIO_MUTE_DETECTED :

outputString = videoFilename + ': Mute voice detected: start('+ str(fStartTS) +') end('+ str(fEndTS) +')'

printoutputString

WriteLog(logFilename, outputString)

defOnPyVideoStateCallback(uiProgress, uiState, ulParam):

globalvideoFilename

outputString = ''

ifuiState == DECODE_START :

outputString = '\r\n'+ videoFilename +': video analyze is starting......'

WriteLog(logFilename, outputString)

elifuiState == DECODE_RUNNING :

outputString = videoFilename + ': video analyze is running, progress: '+ str(uiProgress) +'%'

elifuiState == DECODE_END :

outputString = videoFilename + ': video analyze is ended'

WriteLog(logFilename, outputString)

elifuiState == DECODE_ERROR :

outputString = videoFilename + ': video analyze is error'

WriteLog(logFilename, outputString)

printoutputString

python 两个回调函数:OnPyVideoAnalyzeResultCallback和OnPyVideoStateCallback。

如何把这两个python函数注册成C代码的回调函数呢?

python部分是这样注册滴:

CMPRESULTFUNC = CFUNCTYPE(None, c_ulong, c_ulong, c_ulong, c_ulong)

CMPSTATEFUNC = CFUNCTYPE(None, c_ulong, c_ulong, c_ulong)

iRet = mylib.VideoAnalyzeStart(ulHandle, CMPRESULTFUNC(OnPyVideoAnalyzeResultCallback), CMPSTATEFUNC(OnPyVideoStateCallback))

应用这个来设置:CFUNCTYPE

第一个参数是python回调函数的返回值,如果没有就是None。

第二个及其以后的就是python回调函数的参数类型了。

CMPRESULTFUNC = CFUNCTYPE(None, c_ulong, c_ulong, c_ulong, c_ulong)//创建一个c函数类型的对象工厂,该函数返回值为None,有三个入参,都为unsigned long。

CMPRESULTFUNC(OnPyVideoAnalyzeResultCallback)根据Python可调用对象生成函数。

mylib.VideoAnalyzeStart(ulHandle, CMPRESULTFUNC(OnPyVideoAnalyzeResultCallback), CMPSTATEFUNC(OnPyVideoStateCallback))//设置回调函数

C部分是这样的:

intVideoAnalyzeStart(unsignedlongulHandle, AnalyzeDetectedCallback resultCallback, AnalyzeStateCallback stateCallback)

{

VideoAnalyzeManage* pManager = (VideoAnalyzeManage*)ulHandle;

if(pManager)

{

pManager->SetAnalyzeResultCallback(resultCallback, 0);

pManager->SetStateNotifyCallback(stateCallback, 0);

intiRet = pManager->Start();

returniRet;

}

return-1;

}

C部分不用管。

但是如何确定python函数参数与C函数参数的对应关系呢?

python函数参数与C函数参数的对应表(其实也可以叫ctypes类型表):

一个大坑:需要注意CMPRESULTFUNC(OnPyVideoAnalyzeResultCallback)这个指针函数是有自己的生存空间的,如果生存空间已过,会被释放,C代码再回调的时候,就会使用一个过期指针。

这里建议使用一个全局的python指针。

CMPRESULTFUNC = CFUNCTYPE(c_int, c_ulong, c_ulong, c_ulong, c_ulong)

CMPSTATEFUNC = CFUNCTYPE(c_int, c_ulong, c_ulong, c_ulong)

pResutFunc = CMPRESULTFUNC(OnPyVideoAnalyzeResultCallback)

pStateFunc = CMPSTATEFUNC(OnPyVideoStateCallback)

defmain():

globalpResutFunc

globalpStateFunc

....

iRet = mylib.VideoAnalyzeStart(ulHandle, pResutFunc, pStateFunc)

见官网的解释:

https://docs.python.org/3/library/ctypes.html#ctypes.c_long

Note

Make sure you keep references to CFUNCTYPE() objects as long as they are used from C code. ctypes doesn’t, and if you don’t, they may be garbage collected, crashing your program when a callback is made.

Also, note that if the callback function is called in a thread created outside of Python’s control (e.g. by the foreign code that calls the callback), ctypes creates a new dummy Python thread on every invocation. This behavior is correct for most purposes, but it means that values stored with threading.local will not survive across different callbacks, even when those calls are made from the same C thread.

c向python注册函数_python如何调用C, 如何注册成C的回调函数(python后台程序常用方法)...相关推荐

  1. python做一个登录注册界面_Python 实现简单的登录注册界面

    Python 实现简单的登录注册界面 注意:编写代码之前需要导入很重要的包 import tkinter as tk import pickle from tkinter import message ...

  2. python入门day16——函数的递归调用、二分法、三元表达式、匿名函数

    文章目录 函数的递归调用 递归调用应该分为两个阶段 二分法 三元表达式 匿名函数 函数的递归调用 函数的递归调用:就是在调用一个函数的过程中又直接或间接地调用自己 示例1:直接调用自己 def foo ...

  3. matlab 利用函数的递归调用计算 n,关于递归:递归匿名函数Matlab

    我知道这不是匿名函数的用途,但就像我试图通过匿名函数创建递归函数一样. 递归函数的原型显然是阶乘函数. 问题是在匿名函数中很难区分大小写. 到目前为止我设法做的是: f=@(cn,n,f)eval(' ...

  4. C语言回调函数demo(帮助理解)以海康isapiExternDemo回调函数为例

    参考文章:c语言指针回调函数最全demo实例(简单明了一看就会) 回更 20220303 \demo\base\isapiExternDemo\isapiExternDemo.c 这边海康定义了一个回 ...

  5. ajax form不回调函数,jQuery ajax form提交在IE8下不执行回调函数

    // 上传文件 function myUploadExcel(obj) { var options = { url : "${ctx}/ins/pro/upLoadTempFile.do?f ...

  6. python怎么调用另一个文件的函数_python如何调用另一个py文件的所有函数?

    慕盖茨4494581 在同一个文件夹下调用函数:A.py文件:B.py文件:或调用类:A.py文件:B.py文件:或在不同文件夹下A.py文件的文件路径:E:\PythonProject\winycg ...

  7. python echo函数_python如何调用php文件中的函数详解

    前言 python调用php代码实现思路:php文件可通过在terminal中使用php命令行进行调用,因此可使用python开启子进程执行命令行代码.函数所需的参数可通过命令行传递. 测试环境 1. ...

  8. python跨文件调用函数_python如何调用另一个py文件的所有函数?

    展开全部 在同一个2113文件夹下 调用5261函数: A.py文件: B.py文件: 或 调用类: A.py文件: B.py文件: 或 在不同文4102件夹下 A.py文件的文件路径:E:\Pyth ...

  9. python 运行时间计算_python计算一段代码的运行时间(类和函数)

    使用python的timeit模块可以轻松的获得一段代码的运行时间. 一.获得一个类的运行时间:import timeit as ti gettime = """ imp ...

最新文章

  1. 评价对象检测模型的数字度量:F1分数以及它们如何帮助评估模型的表现
  2. mysql-零基础安装
  3. 如何设计第三方账号登陆?
  4. Java——Arrays类操作数组的工具类
  5. IntelliJ IDEA下的使用git
  6. 设计模式之Strategy(策略模式系列1)
  7. ORACLE的分布式管理
  8. CTPN/CRNN的OCR自然场景文字识别理解(一)
  9. matlab 地理加权回归,混合时空地理加权回归及参数地两步估计.PDF
  10. 智慧化工园区解决方案
  11. 第三方支付和代付区别在哪?
  12. SAP跨公司销售经典场景
  13. 滴滴开源 Booster:移动APP质量优化框架
  14. 中国人民大学计算机考研分数线2020,中国人民大学2020考研国家线-复试分数线-录取分数线 - 希赛网...
  15. timenote时光笔记+android,Time Note时光笔记软件怎么样?Time Note时光笔记有哪些功能特色?...
  16. cad修改快捷键_CAD新手攻略:修剪(TRIM)CAD命令快捷键的使用技巧
  17. 人工智能与数据挖掘的关系
  18. 爬虫玩得好,牢饭吃到饱?这3条底线千万不能碰!
  19. 微信是怎么打造平台型生态商业模式的?
  20. Report中的Drill down

热门文章

  1. 【FLink】Flink checkpoint 实现数据连续计算 恢复机制 案例实战
  2. 【kafka】Kafka Fetch Session 剖析
  3. 【Elasticsearch】Elasticsearch底层系列之Shard Allocation机制
  4. 【Elasticsearch】玩转 Elasticsearch 7.8 的 SQL 功能
  5. 【Linux】性能优化-linux命令nicstat 网络性能监控
  6. 01-windows下Elasticsearch安装
  7. 《spring-boot学习》-06-thymeleaf详解
  8. 云计算实战系列十六(SQL II)
  9. div iframe 显示html,IE中iframe标签显示在DIV之上的问题解决方案
  10. 经典面试题:Integer c=100,d=100,c==d 一定是false吗?