When Python calls c sdk, the returned values do not conform to expectations and Segmentation fault and sdksegmentation
1. the sdk return value is not an int type 1.1 logon function call
DefLogin (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 );
: ParamIp:
: ParamPort:
: ParamUsername:
: ParamPassword:
: ParamDevice_info:
: ParamError_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 ))
ReturnUser_id# C_longlong (user_id). value
1.2 The ID is invalid.
The User ID is used as the handle and is passed into other SDK functions. An error is returned and the handle is invalid. View the negative value. Therefore, it is suspected that the type does not match.
1.3 set the return type 1.3.1 error cause
I checked it online and read the document below. The sdk For Calling C in python returns the int type by default. According to the Function Definition of login C, the LLONG type is returned.
15.17.1.8. Return types
By default functions are assumed to return the Cint
Type. Other return types can be specified by settingrestype
Attribute of the function object.
Here is a more advanced example, it usesstrchr
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 Modification
Set the return value of the sdk function to c_longlong. Solution
SDK. _ dll. CLIENT_Login.restype = c_longlong
2. Segmentation fault is likely to occur in the callback function scenario.
I found a circle on the Internet. Generally, there are two possibilities: memory out-of-bounds or invalid read/write; another is that the function call stack is too deep.
2.1 read/write locks
The Code itself adds the Condition read/write lock, and the buf is also allocated during writing. debugging should not be caused by this issue. Printing logs is not related to read/write operations.
Write
Index = userdata # c_uint (userdata). value
_ Buf_cond.acquire ()
# Time. sleep (0.2)
# Copying images to memory
# _ Pic_buf.buf = pBuf c_char and c_byte Conversion
Try:
Temp = [pBuf [I] for I in xrange (0, RevLen)]
_ Buf_list [index]. buf = struct. pack ('% db' % RevLen, * temp)
# Serial number
_ 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 t Exception, e:
Logger. error ('cache exception: % s' % str (e ))
Finally:
_ Buf_cond.policy ()
_ Buf_cond.release ()
Read
_buf_cond.acquire()
_ Buf_cond.wait (timeout = 15.0)
# Wait for MS to access the data again
# Time. sleep (0.2)
If _ buf_list [self. index]. sn = snap. Sort serial and _ buf_list [self. index]. id = self. index:
Self. save_picture (_ buf_list [self. index]. buf, _ buf_list [self. index]. ext)
Self.info ('for channel % d succeeded, IP: % s, Port: % s' % (channel, self. ip, self. port ))
Pass
_ Buf_cond.release ()
2.2 reduce stack call levels
The callback function is used after the sdk is introduced. Therefore, the callback function definition level is reduced.
2.2.1 before modification
Input the function to the base class. In the base class, the CFUNCTYPE instantiate the function.
Definition in base class
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 is also defined as staticmethod In the subclass.
def _set_callback(self):
try:
if 0 <= self.index < _buf_size:
Self. set_callback (self. _ save_after_recv_pic, self. index) # The function call level is too deep, and segmentation fault is often reported.
Return True
Else:
Self. error ('error in setting the userdata parameter for saving the callback function: % d' % self. index)
Return False
Except t Exception, e:
Self. error ('failed to save the callback function, % s' % str (e ))
Return False
2.2.2 solve the problem after modification
Directly instantiate the callback function in the subclass
self.capture_callback = self.callback(self._save_after_recv_pic)
Directly register the callback function in the subclass
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) # The function call level is too deep, and segmentation fault is often reported.
Return True
Else:
Self. error ('error in setting the userdata parameter for saving the callback function: % d' % self. index)
Return False
Except t Exception, e:
Self. error ('failed to save the callback function, % s' % str (e ))
Return False