python如何调用C, 如何注册成C的回调函数(python后台程序常用方法)

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

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


需要做两个工作:

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

1,python如何调用C语言

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

python代码是这样滴:

[python]  view plain  copy
  1. from ctypes import *  
  2. dynamicLibString = './libcheckVideoFile.so'  
  3. mylib = cdll.LoadLibrary(dynamicLibString)  
  4. ulHandle = mylib.VideoAnalyzeInit(videoFilename)  
  5.     if ulHandle == 0:  
  6.         print 'VideoAnalyzeInit error.'  
  7.         print ''  
  8.           
  9.     mylib.EnableBlackDetected(ulHandle)  
  10.     mylib.EnablePureColorDetected(ulHandle)  
  11.     mylib.EnableFrozenDetected(ulHandle)  
  12.   
  13.   
  14.     mylib.EnableMuteVoiceDetected(ulHandle)  


C代码是这样滴:

[cpp]  view plain  copy
  1. unsigned long VideoAnalyzeInit(char* szFilename)  
  2. {  
  3.     VideoAnalyzeManage* pManager = new VideoAnalyzeManage(szFilename);  
  4.     if(pManager)  
  5.     {  
  6.         int iRet = pManager->Init();  
  7.         if(iRet != 0)  
  8.         {  
  9.             delete pManager;  
  10.             return 0;  
  11.         }  
  12.     }  
  13.     return (unsigned long)pManager;  
  14. }  
  15. void EnableBlackDetected(unsigned long ulHandle)  
  16. {  
  17.     VideoAnalyzeManage* pManager = (VideoAnalyzeManage*)ulHandle;  
  18.     if(pManager)  
  19.     {  
  20.         pManager->EnableBlackDetected();  
  21.     }  
  22. }  


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


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

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


python的回调函数:

[python]  view plain  copy
  1. def OnPyVideoAnalyzeResultCallback(ulStartTS, ulEndTS, ulDetectedType, ulParam):  
  2.     fStartTS = ulStartTS/1000.0  
  3.     fEndTS   = ulEndTS/1000.0  
  4.     outputString = ''  
  5.       
  6.     if ulDetectedType == ALL_BLACK_DETECTED :  
  7.         outputString = videoFilename + ': All black color detected: start(' + str(fStartTS) + ') end(' + str(fEndTS) + ')'  
  8.     elif ulDetectedType == SIMPLE_COLOR_DETECTED :  
  9.         outputString = videoFilename + ': All pure color detected: start(' + str(fStartTS) + ') end(' + str(fEndTS) + ')'  
  10.     elif ulDetectedType == FROZEN_VIDEO_DETECTED :  
  11.         outputString = videoFilename + ': Frozen image detected: start(' + str(fStartTS) + ') end(' + str(fEndTS) + ')'  
  12.     elif ulDetectedType == AUDIO_MUTE_DETECTED :  
  13.         outputString = videoFilename + ': Mute voice detected: start(' + str(fStartTS) + ') end(' + str(fEndTS) + ')'  
  14.     print outputString  
  15.     WriteLog(logFilename, outputString)  
  16.   
  17. def OnPyVideoStateCallback(uiProgress, uiState, ulParam):  
  18.     global videoFilename  
  19.     outputString = ''  
  20.     if uiState == DECODE_START :  
  21.         outputString = '\r\n' + videoFilename + ': video analyze is starting......'  
  22.         WriteLog(logFilename, outputString)  
  23.     elif uiState == DECODE_RUNNING :  
  24.         outputString = videoFilename + ': video analyze is running, progress: ' + str(uiProgress) + '%'  
  25.     elif uiState == DECODE_END :  
  26.         outputString = videoFilename + ': video analyze is ended'  
  27.         WriteLog(logFilename, outputString)  
  28.     elif uiState == DECODE_ERROR :  
  29.         outputString = videoFilename + ': video analyze is error'  
  30.         WriteLog(logFilename, outputString)  
  31.     print outputString  
python 两个回调函数:OnPyVideoAnalyzeResultCallback和OnPyVideoStateCallback。

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

python部分是这样注册滴:

[python]  view plain  copy
  1. CMPRESULTFUNC = CFUNCTYPE(None, c_ulong, c_ulong, c_ulong, c_ulong)  
  2. CMPSTATEFUNC = CFUNCTYPE(None, c_ulong, c_ulong, c_ulong)  
  3.   
  4. 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部分是这样的:

[cpp]  view plain  copy
  1. int VideoAnalyzeStart(unsigned long ulHandle, AnalyzeDetectedCallback resultCallback, AnalyzeStateCallback stateCallback)  
  2. {  
  3.     VideoAnalyzeManage* pManager = (VideoAnalyzeManage*)ulHandle;  
  4.     if(pManager)  
  5.     {  
  6.         pManager->SetAnalyzeResultCallback(resultCallback, 0);  
  7.         pManager->SetStateNotifyCallback(stateCallback, 0);  
  8.         int iRet = pManager->Start();  
  9.         return iRet;  
  10.     }  
  11.     return -1;  
  12. }  
C部分不用管。

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

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


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

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

[python]  view plain  copy
  1. CMPRESULTFUNC = CFUNCTYPE(c_int, c_ulong, c_ulong, c_ulong, c_ulong)  
  2. CMPSTATEFUNC = CFUNCTYPE(c_int, c_ulong, c_ulong, c_ulong)  
  3.   
  4. pResutFunc = CMPRESULTFUNC(OnPyVideoAnalyzeResultCallback)  
  5. pStateFunc = CMPSTATEFUNC(OnPyVideoStateCallback)  
  6.   
  7.   
  8. def main():  
  9.     global pResutFunc  
  10.     global pStateFunc  
  11.     ....  
  12.     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.

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 企业微信回调是指企业微信接收到某个事件后,主动将相关信息推送给注册回调URL。Python作为一种高级编程语言,在企业微信回调中可以使用Python来处理接收到的回调信息。 首先,可以使用Python中的Flask框架来搭建一个简单的Web应用程序,这样就可以接收来自企业微信的回调信息了。通过Flask框架提供的路由功能,可以将回调URL与对应的处理函数关联起来。在处理函数中,可以解析回调信息的内容,如消息的内容、发送者、接收者等,便于后续处理。 其次,对于不同的回调事件,可以编写相应的处理逻辑。比如,当接收到文本消息时,可以编写相应的代码进行文本消息的处理,如进行关键词匹配、自动回复等。当接收到图片、视频等媒体消息时,可以调用企业微信提供的API进行更进一步的处理,如保存到本地、转发给其他群组等。 另外,为了保证安全性,可以在Flask应用程序中加入身份验证的功能,确保只有企业微信发送的回调请求才能被正确处理。可以使用企业微信提供的token进行验证,确保回调URL的安全性。 最后,为了保证回调的可靠性,建议将接收到的回调信息保存到数据库或者日志文件中,以便后续进行查看和分析。可以使用Python中的数据库操作模块来实现数据存储,如MySQL、SQLite等。 总之,通过使用Python编写企业微信回调的处理逻辑,可以实现灵活、高效地处理企业微信回调信息,帮助企业在业务运营中更好地应用企业微信。 ### 回答2: Python企业微信回调是指使用Python编程语言来处理企业微信回调事件。企业微信是一个基于互联网的企业通讯工具,可以通过API来实现与企业微信的集。企业微信回调是指在特定事件发生时,企业微信会向事先注册回调URL发送相关的事件通知,例如用户被添加、用户被删除、用户信息更新等。使用Python编程语言可以编写相应的代码来处理这些回调事件。 在Python中,可以使用第三方库来处理企业微信回调,例如使用Flask框架来创建一个Web应用程序。Flask提供了一个简单而灵活的方式来处理HTTP请求,并且可以方便地与企业微信API进行交互。在这个Web应用程序中,可以定义不同的路由来处理不同的企业微信回调事件。在每个路由的处理函数中,可以获取到企业微信发送过来的相关数据,然后根据需要进行相应的处理,例如保存数据到数据库、发送通知等。 除了使用Flask之外,还可以使用其他Python库来处理企业微信回调,例如使用Django、Tornado等。这些库都提供了不同程度的封装,可以根据自己的需求选择合适的库。 总而言之,Python企业微信回调是通过使用Python编程语言来处理企业微信回调事件的一种方式。可以根据具体需求选择合适的Python库来编写相应的代码来处理企业微信回调事件。 ### 回答3: 企业微信回调是指企业在使用Python开发时,可以通过企业微信提供的API接口实现对企业微信的回调功能。回调是企业微信提供的一种机制,可以方便地将企业内部的业务数据同步到企业微信中,或者将企业微信中的消息通知推送到企业内部的系统中。 在Python中,可以通过使用企业微信提供的Python SDK,来创建一个回调URL,并处理相关的回调消息。首先,需要在企业微信后台配置回调URL,并选择需要接收的事件类型,例如:员变更事件、消息事件等。然后,使用Python SDK中提供的方法,监听服务器的请求,并根据接收到的回调事件进行相应的处理。 比如,当员变更事件发生时,企业微信会向回调URL发送一个POST请求,包含相关的员变更信息。Python开发者可以通过监听到这个请求,并使用SDK提供的方法解析请求体,获取到对应的员变更内容,然后根据业务逻辑进行相应的处理,例如:更新数据库中的员信息、发送通知等。 另外,企业微信还提供了一些特定事件类型的回调,如:外部联系人变更事件、审批事件等。针对这些特定事件,Python开发者可以在回调URL中进行相应的处理逻辑,从而实现企业微信与内部业务系统的数据同步或互通。 总结来说,通过Python企业微信回调,开发者可以实现企业微信与内部系统之间的数据同步和通信,提高企业的工作效率和信息传递的实时性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值