国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

Python調用C的SDK出現返回值不符合預期以及Segmentationfault的解決方法

來源:懂視網 責編:小采 時間:2020-11-27 14:16:16
文檔

Python調用C的SDK出現返回值不符合預期以及Segmentationfault的解決方法

Python調用C的SDK出現返回值不符合預期以及Segmentationfault的解決方法:1、sdk返回值不是int型1.1 登錄函數調用def login(ip, port, username, password, device_info, error_code):"""LLONG CLIENT_Login(char *pchDVRIP, WORD wDVRPort,char *pchUserName
推薦度:
導讀Python調用C的SDK出現返回值不符合預期以及Segmentationfault的解決方法:1、sdk返回值不是int型1.1 登錄函數調用def login(ip, port, username, password, device_info, error_code):"""LLONG CLIENT_Login(char *pchDVRIP, WORD wDVRPort,char *pchUserName

1、sdk返回值不是int型

1.1 登錄函數調用

def login(ip, port, username, password, device_info, error_code):
"""
LLONG CLIENT_Login(
char *pchDVRIP, WORD wDVRPort,
char *pchUserName, char *pchPassword,
LPNET_DEVICEINFO lpDeviceInfo, int *error = 0);
:param ip:
:param port:
:param username:
:param password:
:param device_info:
:param error_code:
:return: LLONG
"""
ip_buffer = c_buffer(ip)
# ip_buffer.encode('utf8')
# user_id = c_longlong(0)
user_id = SDK._dll.CLIENT_Login(byref(ip_buffer), port, username, password, byref(device_info), byref(error_code))
return user_id # c_longlong(user_id).value

1.2 無效的ID

用戶ID作為句柄,傳入其他SDK函數中,報錯,句柄無效。查看出現負值。因此懷疑是類型不匹配

Python調用C的SDK出現返回值不符合預期以及Segmentation fault的解決方法

1.3 設置返回類型

1.3.1 錯誤原因

網上查了下,并看了下文檔,python中調用C的sdk,默認返回的是int型,按照login C版本的函數定義,返回的是LLONG型

15.17.1.8. Return types

By default functions are assumed to return the C int type. Other return types can be specified by setting the restype attribute of the function object.

Here is a more advanced example, it uses the strchr function, which expects a string pointer and a char, and returns a pointer to a string:

>>> strchr = libc.strchr
>>> strchr("abcdef", ord("d")) 
8059983
>>> strchr.restype = c_char_p # c_char_p is a pointer to a string
>>> strchr("abcdef", ord("d"))
'def'
>>> print strchr("abcdef", ord("x"))
None
>>>

1.3.2 修改

設置sdk函數的返回值為c_longlong,問題解決

SDK._dll.CLIENT_Login.restype = c_longlong

2、回調函數場景下大概率出現Segmentation fault

網上找了一圈,一般兩種可能性:內存越界或者讀寫非法; 還有一種就是函數調用棧太深。

2.1 讀寫加鎖

代碼本身就添加了Condition讀寫鎖得,buf也是在寫的時候分配的,多番調試,應該不是這個地方因為的問題。打印日志看,也與讀寫操作無關。

index = userdata # c_uint(userdata).value
_buf_cond.acquire()
# time.sleep(0.2)

# 復制圖片到內存
# _pic_buf.buf = pBuf c_char 和 c_byte轉換
try:
 temp = [pBuf[i] for i in xrange(0, RevLen)]
 _buf_list[index].buf = struct.pack('%db' % RevLen, *temp)
 # 序列號
 _buf_list[index].sn = c_ulong(CmdSerial).value
 _buf_list[index].id = index
 _buf_list[index].size = c_uint(RevLen).value
 _buf_list[index].ext = 'jpeg' # encode_dict.get(EncodeType, 'jpeg')
except Exception, e:
 logger.error('截圖緩存發生異常:%s' % str(e))
finally:
 _buf_cond.notify()
 _buf_cond.release()
_buf_cond.acquire()
_buf_cond.wait(timeout=15.0)
# 等待200ms再訪問數據
# time.sleep(0.2)
if _buf_list[self.index].sn == snap.CmdSerial and _buf_list[self.index].id == self.index:
 self.save_picture(_buf_list[self.index].buf, _buf_list[self.index].ext)
 self.info('針對通道%d截圖成功,IP:%s,Port:%s' % (channel, self.ip, self.port))
 pass
_buf_cond.release()

2.2 減少棧調用層次

由于引入這個sdk之后,使用了回調函數。因此將回調函數定義層次減少。

2.2.1 修改前

傳入函數給基類,在基類中CFUNCTYPE實例化函數

基類中定義

self.callback = CFUNCTYPE(c_void_p, c_longlong, POINTER(c_byte), c_uint, c_uint, c_ulong, c_ulonglong)
def set_callback(self, save_after_recv_pic, index):
 self.dll.CLIENT_SetSnapRevCallBack(self._callback(save_after_recv_pic), index)
子類中定義,_save_after_recv_pic也在子類中定義為staticmethod
def _set_callback(self):
 try:
 if 0 <= self.index < _buf_size:
 self.set_callback(self._save_after_recv_pic, self.index) # 函數調用層次太深,經常報segmentation fault
 return True
 else:
 self.error('設置截圖保存回調函數的userdata參數錯誤:%d' % self.index)
 return False
 except Exception, e:
 self.error('設置截圖保存回調函數失敗,%s' % str(e))
 return False
 

2.2.2 修改后問題解決

子類中直接實例化回調函數

self.capture_callback = self.callback(self._save_after_recv_pic)
子類中直接注冊回調函數
def _set_callback(self):
 try:
 if 0 <= self.index < _buf_size:
 self.dll.CLIENT_SetSnapRevCallBack(self.capture_callback, self.index)
 # self.set_callback(self._save_after_recv_pic, self.index) # 函數調用層次太深,經常報segmentation fault
 return True
 else:
 self.error('設置截圖保存回調函數的userdata參數錯誤:%d' % self.index)
 return False
 except Exception, e:
 self.error('設置截圖保存回調函數失敗,%s' % str(e))
 return False

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

Python調用C的SDK出現返回值不符合預期以及Segmentationfault的解決方法

Python調用C的SDK出現返回值不符合預期以及Segmentationfault的解決方法:1、sdk返回值不是int型1.1 登錄函數調用def login(ip, port, username, password, device_info, error_code):"""LLONG CLIENT_Login(char *pchDVRIP, WORD wDVRPort,char *pchUserName
推薦度:
標簽: 出現 解決 python
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 亚洲国产精品综合久久网络 | 欧洲日韩视频二区在线 | 在线免费观看国产视频 | 99久久精品免费国产一区二区三区 | 成人看片黄a毛片 | 中国特黄毛片 | 精品在线免费播放 | 亚洲欧洲久久 | 国产在线视频一区 | 亚洲精品免费在线 | 欧美成人看片一区二区三区尤物 | 国产日韩一区二区三区在线观看 | 精品日韩欧美国产一区二区 | 精品国产一区二区三区19 | 视频在线观看一区 | 国产欧美在线播放 | 韩国精品一区二区久久 | 国产91久久精品一区二区 | 91一区二区三区 | 在线观看网站国产 | 日本v片免费一区二区三区 欧洲精品欧美精品 | 国产高清a毛片在线看 | 亚洲欧洲中文字幕 | 亚洲成a人一区二区三区 | 欧美日韩极品 | 日韩一区二区三区精品 | 久久久久国产精品美女毛片 | 人人爽天天碰天天躁夜夜躁 | 日韩精品欧美一区二区三区 | 亚洲国产成人久久综合碰 | 欧美性xxxxx极品老少 | 高清不卡一区 | 夜精品a一区二区三区 | 91麻豆网 | 国产精品va在线观看无 | 久草综合网 | 亚洲专区欧美专区 | 国产精品一区二区午夜嘿嘿嘿小说 | 欧美日韩中文 | 久久久久久夜精品精品免费啦 | 国产高清美女一级毛片久久 |