<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題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關(guān)鍵字專題關(guān)鍵字專題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調(diào)用C的SDK出現(xiàn)返回值不符合預(yù)期以及Segmentationfault的解決方法

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

        Python調(diào)用C的SDK出現(xiàn)返回值不符合預(yù)期以及Segmentationfault的解決方法

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

        1、sdk返回值不是int型

        1.1 登錄函數(shù)調(diào)用

        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函數(shù)中,報錯,句柄無效。查看出現(xiàn)負值。因此懷疑是類型不匹配

        Python調(diào)用C的SDK出現(xiàn)返回值不符合預(yù)期以及Segmentation fault的解決方法

        1.3 設(shè)置返回類型

        1.3.1 錯誤原因

        網(wǎng)上查了下,并看了下文檔,python中調(diào)用C的sdk,默認返回的是int型,按照login C版本的函數(shù)定義,返回的是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 修改

        設(shè)置sdk函數(shù)的返回值為c_longlong,問題解決

        SDK._dll.CLIENT_Login.restype = c_longlong

        2、回調(diào)函數(shù)場景下大概率出現(xiàn)Segmentation fault

        網(wǎng)上找了一圈,一般兩種可能性:內(nèi)存越界或者讀寫非法; 還有一種就是函數(shù)調(diào)用棧太深。

        2.1 讀寫加鎖

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

        index = userdata # c_uint(userdata).value
        _buf_cond.acquire()
        # time.sleep(0.2)
        
        # 復(fù)制圖片到內(nèi)存
        # _pic_buf.buf = pBuf c_char 和 c_byte轉(zhuǎn)換
        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('截圖緩存發(fā)生異常:%s' % str(e))
        finally:
         _buf_cond.notify()
         _buf_cond.release()
        _buf_cond.acquire()
        _buf_cond.wait(timeout=15.0)
        # 等待200ms再訪問數(shù)據(jù)
        # 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 減少棧調(diào)用層次

        由于引入這個sdk之后,使用了回調(diào)函數(shù)。因此將回調(diào)函數(shù)定義層次減少。

        2.2.1 修改前

        傳入函數(shù)給基類,在基類中CFUNCTYPE實例化函數(shù)

        基類中定義

        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) # 函數(shù)調(diào)用層次太深,經(jīng)常報segmentation fault
         return True
         else:
         self.error('設(shè)置截圖保存回調(diào)函數(shù)的userdata參數(shù)錯誤:%d' % self.index)
         return False
         except Exception, e:
         self.error('設(shè)置截圖保存回調(diào)函數(shù)失敗,%s' % str(e))
         return False
         

        2.2.2 修改后問題解決

        子類中直接實例化回調(diào)函數(shù)

        self.capture_callback = self.callback(self._save_after_recv_pic)
        子類中直接注冊回調(diào)函數(shù)
        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) # 函數(shù)調(diào)用層次太深,經(jīng)常報segmentation fault
         return True
         else:
         self.error('設(shè)置截圖保存回調(diào)函數(shù)的userdata參數(shù)錯誤:%d' % self.index)
         return False
         except Exception, e:
         self.error('設(shè)置截圖保存回調(diào)函數(shù)失敗,%s' % str(e))
         return False

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

        文檔

        Python調(diào)用C的SDK出現(xiàn)返回值不符合預(yù)期以及Segmentationfault的解決方法

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

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 免费在线视频一区| 亚洲大片免费观看| 国产亚洲3p无码一区二区| 久久亚洲AV成人无码| 国产成人 亚洲欧洲| 国产永久免费高清在线| 成年美女黄网站色大免费视频| 亚洲最大av无码网址| 久久亚洲精品国产亚洲老地址| a级片在线免费看| 日本一道综合久久aⅴ免费| 亚洲处破女AV日韩精品| 亚洲国产av玩弄放荡人妇 | 亚洲三级在线观看| 一个人免费高清在线观看| 国产AV无码专区亚洲精品| 久久免费精品一区二区| 亚洲成aⅴ人片久青草影院| 亚洲欧洲日韩国产一区二区三区| 成人免费视频77777| 亚洲AV电影天堂男人的天堂| 久久笫一福利免费导航| 中文字幕在线观看亚洲| 免费看黄视频网站| 精品女同一区二区三区免费播放| 亚洲国产午夜福利在线播放| 亚洲av成人一区二区三区观看在线| 国产jizzjizz免费看jizz| 亚洲日产乱码一二三区别| 国产一卡二卡3卡四卡免费| 亚洲色www永久网站| 最近高清中文字幕免费| 亚洲a一级免费视频| 久久成人无码国产免费播放| 亚洲精品~无码抽插| 0588影视手机免费看片| 日韩亚洲AV无码一区二区不卡| 全免费a级毛片免费看| 亚洲人色大成年网站在线观看| 西西大胆无码视频免费| 女人裸身j部免费视频无遮挡|