Python calls C SDK with return value not expected and segmentation fault workaround

Source: Internet
Author: User
Tags ord

1. The SDK return value is not int type

1.1 Login function calls

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);
:p Aram IP:
:p Aram Port:
:p Aram Username:
:p Aram Password:
:p Aram Device_info:
:p Aram 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 Invalid ID

User ID as a handle, passed in to other SDK functions, error, invalid handle. View a negative value appears. So the suspicion is type mismatch

1.3 Setting the return type

1.3.1 Cause of error

Check the Web, and read the following document, Python called C's SDK, the default is to return the int type, according to the login C version of the function definition, the return is Llong type

15.17.1.8. Return types

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

Here's a more advanced example, it uses strchr the function, which expects a string pointer and a char, and returns a Poin ter 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 ("ABCD EF ", Ord (" X ")) none>>>

1.3.2 Modification

Set the return value of the SDK function to C_longlong, solve the problem

Sdk._dll. Client_login.restype = C_longlong

2. Segmentation fault of large probability appearing in callback function scene

On the internet to find a lap, the general two possibilities: memory out of bounds or read and write illegal, there is also a function call stack too deep.

2.1 Read and Write lock

The code itself added condition read-write lock, BUF is also in the writing time allocation, multiple debugging, should not be this place because of the problem. The print log is also independent of read and write operations.

Write

index = UserData  # c_uint (userdata). Value_buf_cond.acquire () # time.sleep (0.2) # Copy picture 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 Exception, E:    logger.error (' Cache exception:%s '% str (e)) finally:    _buf_cond.notify ()    _buf_cond.release ()
Read
_buf_cond.acquire ()
_buf_cond.wait (timeout=15.0) # wait 200ms again to access 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 (' Success for channel%d, ip:%s,port:%s '% (channel, SELF.IP, Self.port))    pass_buf_cond.release ()

2.2 Reduce stack Call hierarchy

Since this SDK was introduced, a callback function was used. Therefore, the callback function definition hierarchy is reduced.

2.2.1 Before modification

Pass-through function to base class, Cfunctype instantiation function in base class

defined 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)
Subclasses, _save_after_recv_pic are also defined in subclasses as Staticmethod
def _set_callback (self):    try:        if 0 <= self.index < _buf_size:
            Self.set_callback (Self._save_after_recv_pic, Self.index)   # function call hierarchy too deep, often reported segmentation fault            return True        else:            self.error (' Set save callback function UserData parameter error:%d '% self.index)            return False    except Exception, E:        Self.error (' Set save callback function failed,%s '% str (e))        return False

2.2.2 Problem resolution after modification

Direct instantiation of callback functions in subclasses

Self.capture_callback = Self.callback (self._save_after_recv_pic)
Directly registering a callback function in a 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) # function call hierarchy too deep, often reported segmentation fault return True else:self.error (' Set save callback function UserData parameter error:%d '% self.index) return False except Exception, E:self.error (' Set save callback function failed,%s '% str ( e)) return False 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.