@@ -52,7 +52,7 @@ def _compare_values(self, value1, value2):
5252
5353
5454 # This method is called during Out record processing to return the
55- # underlying value in Python format.
55+ # underlying value in EPICS format.
5656 def _read_value (self , record ):
5757 return record .read_val ()
5858
@@ -240,6 +240,13 @@ def _Device_Out(*args, **kargs):
240240mbbo = _Device_Out ('mbbo' , c_uint16 , fields .DBF_SHORT , NO_CONVERT )
241241
242242
243+ def _string_at (value , count ):
244+ # Need string_at() twice to ensure string is size limited *and* null
245+ # terminated.
246+ value = ctypes .string_at (ctypes .string_at (value , count ))
247+ # Convert bytes to unicode string
248+ return value .decode (errors = 'replace' )
249+
243250class EpicsString :
244251 _fields_ = ['UDF' , 'VAL' ]
245252 _epics_rc_ = EPICS_OK
@@ -249,13 +256,20 @@ class EpicsString:
249256 def _value_to_epics (self , value ):
250257 # It's a little odd: we can't simply construct a value from the byte
251258 # string, but we can update the array in an existing value.
252- # Value being written must be a string.
259+ # Value being written must be a string, and will be automatically null
260+ # terminated where possible.
253261 result = self ._ctype_ ()
254262 result .value = value .encode ()
255263 return result
256264
257265 def _epics_to_value (self , epics ):
258- return epics .value .decode (errors = 'replace' )
266+ return _string_at (epics , 40 )
267+
268+ def _read_value (self , record ):
269+ # For strings we need to take a copy of the value read
270+ result = self ._ctype_ ()
271+ result .value = record .read_val ().value
272+ return result
259273
260274
261275class stringin (EpicsString , ProcessDeviceSupportIn ):
@@ -400,7 +414,7 @@ def _value_to_epics(self, value):
400414 return encode_string (value , getattr (self , '_nelm' , None ))
401415
402416 def _epics_to_value (self , value ):
403- return value .decode ( errors = 'replace' )
417+ return _string_at ( value .ctypes , len ( value ) )
404418
405419
406420class long_stringin (LongStringBase , ProcessDeviceSupportIn ):
0 commit comments