chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] FFI string with embedded nulls


From: Zbigniew
Subject: Re: [Chicken-users] FFI string with embedded nulls
Date: Wed, 3 Aug 2005 13:24:18 -0500

Thought I got rid of all those invisible embedded control chars. 
Let's try again.

Toby,

Here are two examples.  In one I create the string on the heap and
return it as a scheme-object from the C code.  In the other I write
directly into a scheme string, using a locative as the pointer. 
Neither probably works with UTF-8.  You didn't specify how the to-len
was computed, so I assume it is a function of the from-len.  Here is
an example transcript; it assumes you saved the examples to
nullstr.scm and ran csc -s nullstr.scm.

#;1> (use nullstr)
; loading ./nullstr.so ...
#;2> (foo "abc")
"bcd"
#;3> (foo2 "abc")
"bcd"
#;4> (byte-vector->string (byte-vector 66 67 0 255 68 69))
"address@hidden"
#;5> (foo #4)
"address@hidden"
#;13> (foo2 (foo #4))
"DE\^B\^AFG"

;; nullstr.scm
;; Common

(use lolevel)

#>
/* Copy fromlen bytes from FROM to TO adding 1 to each byte */
unsigned int foo(char *to, char *from, unsigned int fromlen) {
  int i;
  for (i = 0; i < fromlen; i++) {
         to[i] = from[i] + 1;
  }
  return fromlen;
}
<#

;; Destination string is same size as source
(define (compute-to-len from)
  (string-length from))

;; Example 1

(define _foo
  (foreign-primitive scheme-object ((c-pointer to) (c-string from)
                                    (integer fromlen) (integer tolen)) #<<EOF
    C_word *a;
    if (!foo(to, from, fromlen))
      return(NULL);
    a = C_alloc(C_SIZEOF_STRING(tolen));
    return(C_string(&a, tolen, to));
EOF
))                  


(define (foo from)
  (##sys#check-string from 'foo)
  (let* ((to-len (compute-to-len from))
         (to (allocate to-len)))
    (let ((result (_foo to from (string-length from) to-len)))
      (free to)
      result)))

;; Example 2

(define _foo2 (foreign-lambda integer "foo" c-pointer c-string integer))

(define (foo2 from)
  (##sys#check-string from 'foo)
  (let* ((to-len (compute-to-len from))
         (to (make-string to-len))
         (to-ptr (make-locative to)))
    (_foo2 to-ptr from (string-length from))
    to))
    

On 8/2/05, Toby Butzon <address@hidden> wrote:
> Howdy,
> 
> This all goes on the assumption that Scheme and Chicken are OK even with
> a string with embedded nulls (e.g., "foo\0bar"). That's true, right?
> 
> Now then, I have a function that looks vaguely like:
> 
> unsigned int foo(char *to, char *from, unsigned int fromlen);
> 
> which reads ``from'' and fills some result based on that into a
> pre-allocated (via malloc() or, in Chicken, (allocate ...)) ``to''.
> Both strings may have embedded nulls: ``fromlen'' therefore tells the
> function how long ``from'' is (since strlen() won't work), and the
> return value is used similarly by the caller.
> 
> So what I'm trying to do in Chicken is create a function (foo from) that
> calls the C function and returns the appropriate string, already filled
> out as a Scheme string (and the memory allocated for ``to'' already
> freed).
> 
> I'm stumped. How do I get the string to turn into a Scheme string
> without truncating it at the first embedded null?
> 
> -- TB
> 
> 
> 
> _______________________________________________
> Chicken-users mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/chicken-users
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]