Heim  >  Artikel  >  Backend-Entwicklung  >  Der Rückgabewert, wenn Python das C SDK aufruft, entspricht nicht den Erwartungen und der Lösung für den Segmentierungsfehler

Der Rückgabewert, wenn Python das C SDK aufruft, entspricht nicht den Erwartungen und der Lösung für den Segmentierungsfehler

高洛峰
高洛峰Original
2017-03-20 11:04:101984Durchsuche

1、sdk返回值不是int型

1.1 登录函数调用

def login(ip, port, username, passwort, device_info, error_code):
"""
LLONG CLIENT_Login(
char *pchDVRIP, WORD wDVRPort,
char *pchUserName, char *pchPassword,
LPNET_DEVICINFO lpDeviceInfo, int *error = 0);
:param ip:
:param port:
:param Benutzername:
:param Passwort:
:param Geräteinfo:
: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, Benutzername, Passwort, byref(device_info), byref(error_code))
return user_id # c_longlong(user_id).value

1.2 的的ID疑是类型不匹配

Python调用C的SDK出现返回值不符合预期以及Segmentation fault的解决方法 

1.3 设置返回类型>1.3.1 Python

中调用C的sdk,默认返回的是int型,按照login C版本的函数定义,返回的是LLONG型

15.17.1.8. Rückgabetypen

Standardmäßig wird davon ausgegangen, dass Funktionen den Typ C

zurückgeben. Andere Rückgabetypen können durch Festlegen des -Attributs der Funktion Objekt

angegeben werden.
Hier ist ein fortgeschritteneres Beispiel, es verwendet die Funktion

, die ein stringint Zeiger und ein Zeichen und gibt einen Zeiger auf einen String zurück:restype1.3.2 修改

设置sdkstrchr函数的返回值为c_longlong,问题解决

SDK._dll.CLIENT_Login.restype =. c_longlong
>>> 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
>>>

 

2、回调函数场景下大概率出现S Segmentierungsfehler

网上找了一圈,一般两种可能性:内存越界或者读写非法; 还有一种就是函数调用栈太深。

2.1 读写加锁

代码本身就添加了Condition读写锁得, buf也是在写的时候分配的, 多番调试, 应该不是这个地方因为的问题。打印日志看,也与读写操作无关。

 

2.2函数。因此将回调函数定义层次减少.

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()
2.2.1
_buf_cond.acquire()
基类2.2.2. 修改后问题解决
_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()

子类中直接实例化回调函数

Das obige ist der detaillierte Inhalt vonDer Rückgabewert, wenn Python das C SDK aufruft, entspricht nicht den Erwartungen und der Lösung für den Segmentierungsfehler. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn