diff --git a/pygmt/clib/conversion.py b/pygmt/clib/conversion.py index bd19a38d591..eb8daa61da1 100644 --- a/pygmt/clib/conversion.py +++ b/pygmt/clib/conversion.py @@ -296,6 +296,32 @@ def sequence_to_ctypes_array(sequence: Sequence, ctype, size: int) -> ctp.Array return (ctype * size)(*sequence) +def strings_to_ctypes_array(strings: Sequence[str]) -> ctp.Array: + """ + Convert a sequence (e.g., a list) of strings into a ctypes array. + + Parameters + ---------- + strings + A sequence of strings. + + Returns + ------- + ctypes_array + A ctypes array of strings. + + Examples + -------- + >>> strings = ["first", "second", "third"] + >>> ctypes_array = strings_to_ctypes_array(strings) + >>> type(ctypes_array) + + >>> [s.decode() for s in ctypes_array] + ['first', 'second', 'third'] + """ + return (ctp.c_char_p * len(strings))(*[s.encode() for s in strings]) + + def array_to_datetime(array): """ Convert a 1-D datetime array from various types into numpy.datetime64. diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 2caa8e55cd0..0640ba6ae20 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -20,6 +20,7 @@ as_c_contiguous, dataarray_to_matrix, sequence_to_ctypes_array, + strings_to_ctypes_array, vectors_to_arrays, ) from pygmt.clib.loading import load_libgmt @@ -897,13 +898,9 @@ def put_vector(self, dataset, column, vector): gmt_type = self._check_dtype_and_dim(vector, ndim=1) if gmt_type in (self["GMT_TEXT"], self["GMT_DATETIME"]): - vector_pointer = (ctp.c_char_p * len(vector))() if gmt_type == self["GMT_DATETIME"]: - vector_pointer[:] = np.char.encode( - np.datetime_as_string(array_to_datetime(vector)) - ) - else: - vector_pointer[:] = np.char.encode(vector) + vector = np.datetime_as_string(array_to_datetime(vector)) + vector_pointer = strings_to_ctypes_array(vector) else: vector_pointer = vector.ctypes.data_as(ctp.c_void_p) status = c_put_vector( @@ -960,13 +957,12 @@ def put_strings(self, dataset, family, strings): restype=ctp.c_int, ) - strings_pointer = (ctp.c_char_p * len(strings))() - strings_pointer[:] = np.char.encode(strings) - family_int = self._parse_constant( family, valid=FAMILIES, valid_modifiers=METHODS ) + strings_pointer = strings_to_ctypes_array(strings) + status = c_put_strings( self.session_pointer, family_int, dataset, strings_pointer )