+
+(declaim (type (sfunction * system-area-pointer) %make-alien-string))
+(defun %make-alien-string (string &key (start 0) end
+ (external-format :default)
+ (null-terminate t))
+ ;; FIXME: This is slow. We want a function to get the length of the
+ ;; encoded string so we can allocate the foreign memory first and
+ ;; encode directly there.
+ (let* ((octets (string-to-octets string
+ :start start :end end
+ :external-format external-format
+ :null-terminate null-terminate))
+ (count (length octets))
+ (buf (%make-alien (* 8 count))))
+ (sb!kernel:copy-ub8-to-system-area octets 0 buf 0 count)
+ buf))
+
+(defun make-alien-string (string &rest rest
+ &key (start 0) end
+ (external-format :default)
+ (null-terminate t))
+ "Copy part of STRING delimited by START and END into freshly
+allocated foreign memory, freeable using free(3) or FREE-ALIEN.
+Returns the allocated string as a (* CHAR) alien, and the number of
+bytes allocated as secondary value.
+
+The string is encoded using EXTERNAL-FORMAT. If NULL-TERMINATE is
+true (the default), the alien string is terminated by an additional
+null byte.
+"
+ (declare (ignore start end external-format null-terminate))
+ (multiple-value-bind (sap bytes)
+ (apply #'%make-alien-string string rest)
+ (values (%sap-alien sap (parse-alien-type '(* char) nil))
+ bytes)))
+
+(define-compiler-macro make-alien-string (&rest args)
+ `(multiple-value-bind (sap bytes) (%make-alien-string ,@args)
+ (values (%sap-alien sap ',(parse-alien-type '(* char) nil))
+ bytes)))