This article introduces how to solve the unexpected returned values in Python c sdk call and Segmentationfault. 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 CintType. Other return types can be specified by settingrestypeAttribute of the function object.
Here is a more advanced example, it usesstrchrFunction, 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) # copy an image to memory # _ pic_buf.buf = pBuf c_char and c_byte convert 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 (serial ). value _ buf_list [index]. id = index _ buf_list [index]. size = c_uint (RevLen ). value _ buf_list [index]. ext = 'jpeg '# encode_dict.get (EncodeType, 'jpeg') failed t Exception, e: logger. error ('cache exception: % s' % str (e) finally: _ buf_cond.y Y () _ buf_cond.release ()
Read
_buf_cond.acquire()
_ Buf_cond.wait (timeout = 15.0) # wait for MS to access the data # 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 ('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) # if the function call level is too deep, segmentation fault 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) # if the function call level is too deep, segmentation fault 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
The above is the details about the solution for returning values that do not conform to expectations and Segmentation fault when Python calls c sdk. For more information, see other related articles in the first PHP community!